@mohasinac/appkit 4.34.1 → 4.35.1

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 (243) hide show
  1. package/dist/_internal/client/features/lottery/LotteryAdminEditView.js +32 -2
  2. package/dist/features/auth/actions/profile-actions.d.ts +14 -1
  3. package/dist/features/auth/actions/profile-actions.js +16 -2
  4. package/dist/features/tester/components/TesterChecklistStepRow.d.ts +9 -1
  5. package/dist/features/tester/components/TesterChecklistStepRow.js +31 -2
  6. package/dist/features/tester/components/TesterHubView.js +8 -0
  7. package/dist/features/tester/schemas/firestore.d.ts +109 -0
  8. package/dist/features/tester/schemas/firestore.js +14 -0
  9. package/dist/features/tester/seed-data/_money-flows.d.ts +23 -0
  10. package/dist/features/tester/seed-data/_money-flows.js +430 -0
  11. package/dist/features/tester/seed-data/authored/_types.d.ts +33 -0
  12. package/dist/features/tester/seed-data/authored/_types.js +35 -0
  13. package/dist/features/tester/seed-data/authored/account-auth__profile-settings.d.ts +2 -0
  14. package/dist/features/tester/seed-data/authored/account-auth__profile-settings.js +207 -0
  15. package/dist/features/tester/seed-data/authored/account-auth__signup-login.d.ts +2 -0
  16. package/dist/features/tester/seed-data/authored/account-auth__signup-login.js +298 -0
  17. package/dist/features/tester/seed-data/authored/account-auth__testing-program--admin.d.ts +2 -0
  18. package/dist/features/tester/seed-data/authored/account-auth__testing-program--admin.js +33 -0
  19. package/dist/features/tester/seed-data/authored/account-auth__testing-program.d.ts +2 -0
  20. package/dist/features/tester/seed-data/authored/account-auth__testing-program.js +138 -0
  21. package/dist/features/tester/seed-data/authored/addresses__address-filters.d.ts +2 -0
  22. package/dist/features/tester/seed-data/authored/addresses__address-filters.js +36 -0
  23. package/dist/features/tester/seed-data/authored/addresses__postal-lookup.d.ts +2 -0
  24. package/dist/features/tester/seed-data/authored/addresses__postal-lookup.js +75 -0
  25. package/dist/features/tester/seed-data/authored/addresses__postal-validation.d.ts +2 -0
  26. package/dist/features/tester/seed-data/authored/addresses__postal-validation.js +72 -0
  27. package/dist/features/tester/seed-data/authored/addresses__state-picker.d.ts +2 -0
  28. package/dist/features/tester/seed-data/authored/addresses__state-picker.js +54 -0
  29. package/dist/features/tester/seed-data/authored/addresses__unban-request.d.ts +2 -0
  30. package/dist/features/tester/seed-data/authored/addresses__unban-request.js +39 -0
  31. package/dist/features/tester/seed-data/authored/admin__bans-and-trust.d.ts +2 -0
  32. package/dist/features/tester/seed-data/authored/admin__bans-and-trust.js +226 -0
  33. package/dist/features/tester/seed-data/authored/admin__blog-faqs.d.ts +2 -0
  34. package/dist/features/tester/seed-data/authored/admin__blog-faqs.js +82 -0
  35. package/dist/features/tester/seed-data/authored/admin__bulk-actions.d.ts +2 -0
  36. package/dist/features/tester/seed-data/authored/admin__bulk-actions.js +177 -0
  37. package/dist/features/tester/seed-data/authored/admin__bundles.d.ts +2 -0
  38. package/dist/features/tester/seed-data/authored/admin__bundles.js +97 -0
  39. package/dist/features/tester/seed-data/authored/admin__buyer-data-admin.d.ts +2 -0
  40. package/dist/features/tester/seed-data/authored/admin__buyer-data-admin.js +232 -0
  41. package/dist/features/tester/seed-data/authored/admin__catalog-listings.d.ts +2 -0
  42. package/dist/features/tester/seed-data/authored/admin__catalog-listings.js +306 -0
  43. package/dist/features/tester/seed-data/authored/admin__category-brand-authoring.d.ts +2 -0
  44. package/dist/features/tester/seed-data/authored/admin__category-brand-authoring.js +158 -0
  45. package/dist/features/tester/seed-data/authored/admin__classifieds-digitalcodes-live.d.ts +2 -0
  46. package/dist/features/tester/seed-data/authored/admin__classifieds-digitalcodes-live.js +78 -0
  47. package/dist/features/tester/seed-data/authored/admin__content-deletes.d.ts +2 -0
  48. package/dist/features/tester/seed-data/authored/admin__content-deletes.js +261 -0
  49. package/dist/features/tester/seed-data/authored/admin__content-marketing.d.ts +2 -0
  50. package/dist/features/tester/seed-data/authored/admin__content-marketing.js +151 -0
  51. package/dist/features/tester/seed-data/authored/admin__coupons.d.ts +2 -0
  52. package/dist/features/tester/seed-data/authored/admin__coupons.js +214 -0
  53. package/dist/features/tester/seed-data/authored/admin__events-raffles-spin.d.ts +2 -0
  54. package/dist/features/tester/seed-data/authored/admin__events-raffles-spin.js +160 -0
  55. package/dist/features/tester/seed-data/authored/admin__media-watermark.d.ts +2 -0
  56. package/dist/features/tester/seed-data/authored/admin__media-watermark.js +104 -0
  57. package/dist/features/tester/seed-data/authored/admin__orders-fulfillment.d.ts +2 -0
  58. package/dist/features/tester/seed-data/authored/admin__orders-fulfillment.js +350 -0
  59. package/dist/features/tester/seed-data/authored/admin__prize-draws-lotteries.d.ts +2 -0
  60. package/dist/features/tester/seed-data/authored/admin__prize-draws-lotteries.js +105 -0
  61. package/dist/features/tester/seed-data/authored/admin__site-system.d.ts +2 -0
  62. package/dist/features/tester/seed-data/authored/admin__site-system.js +590 -0
  63. package/dist/features/tester/seed-data/authored/admin__uncovered-admin-pages.d.ts +2 -0
  64. package/dist/features/tester/seed-data/authored/admin__uncovered-admin-pages.js +235 -0
  65. package/dist/features/tester/seed-data/authored/admin__users-trust.d.ts +2 -0
  66. package/dist/features/tester/seed-data/authored/admin__users-trust.js +569 -0
  67. package/dist/features/tester/seed-data/authored/buying__bidding.d.ts +2 -0
  68. package/dist/features/tester/seed-data/authored/buying__bidding.js +417 -0
  69. package/dist/features/tester/seed-data/authored/buying__browsing-search.d.ts +2 -0
  70. package/dist/features/tester/seed-data/authored/buying__browsing-search.js +653 -0
  71. package/dist/features/tester/seed-data/authored/buying__buying-checkout.d.ts +2 -0
  72. package/dist/features/tester/seed-data/authored/buying__buying-checkout.js +533 -0
  73. package/dist/features/tester/seed-data/authored/buying__buying-coupons.d.ts +2 -0
  74. package/dist/features/tester/seed-data/authored/buying__buying-coupons.js +379 -0
  75. package/dist/features/tester/seed-data/authored/buying__cart.d.ts +2 -0
  76. package/dist/features/tester/seed-data/authored/buying__cart.js +1171 -0
  77. package/dist/features/tester/seed-data/authored/buying__image-tile-layout.d.ts +2 -0
  78. package/dist/features/tester/seed-data/authored/buying__image-tile-layout.js +140 -0
  79. package/dist/features/tester/seed-data/authored/buying__my-orders.d.ts +2 -0
  80. package/dist/features/tester/seed-data/authored/buying__my-orders.js +257 -0
  81. package/dist/features/tester/seed-data/authored/buying__offers.d.ts +2 -0
  82. package/dist/features/tester/seed-data/authored/buying__offers.js +1111 -0
  83. package/dist/features/tester/seed-data/authored/buying__order-status-lifecycle.d.ts +2 -0
  84. package/dist/features/tester/seed-data/authored/buying__order-status-lifecycle.js +252 -0
  85. package/dist/features/tester/seed-data/authored/buying__product-detail.d.ts +2 -0
  86. package/dist/features/tester/seed-data/authored/buying__product-detail.js +387 -0
  87. package/dist/features/tester/seed-data/authored/buying__return-request.d.ts +2 -0
  88. package/dist/features/tester/seed-data/authored/buying__return-request.js +152 -0
  89. package/dist/features/tester/seed-data/authored/buying__reviews-pagination.d.ts +2 -0
  90. package/dist/features/tester/seed-data/authored/buying__reviews-pagination.js +242 -0
  91. package/dist/features/tester/seed-data/authored/buying__reviews.d.ts +2 -0
  92. package/dist/features/tester/seed-data/authored/buying__reviews.js +113 -0
  93. package/dist/features/tester/seed-data/authored/buying__user-dashboard-extras.d.ts +2 -0
  94. package/dist/features/tester/seed-data/authored/buying__user-dashboard-extras.js +283 -0
  95. package/dist/features/tester/seed-data/authored/buying__user-dashboard-navigation.d.ts +2 -0
  96. package/dist/features/tester/seed-data/authored/buying__user-dashboard-navigation.js +167 -0
  97. package/dist/features/tester/seed-data/authored/buying__user-uncovered-pages.d.ts +2 -0
  98. package/dist/features/tester/seed-data/authored/buying__user-uncovered-pages.js +90 -0
  99. package/dist/features/tester/seed-data/authored/buying__wishlist-history.d.ts +2 -0
  100. package/dist/features/tester/seed-data/authored/buying__wishlist-history.js +344 -0
  101. package/dist/features/tester/seed-data/authored/community-support__public-profile.d.ts +2 -0
  102. package/dist/features/tester/seed-data/authored/community-support__public-profile.js +53 -0
  103. package/dist/features/tester/seed-data/authored/community-support__support-tickets.d.ts +2 -0
  104. package/dist/features/tester/seed-data/authored/community-support__support-tickets.js +76 -0
  105. package/dist/features/tester/seed-data/authored/content-discovery__blog.d.ts +2 -0
  106. package/dist/features/tester/seed-data/authored/content-discovery__blog.js +93 -0
  107. package/dist/features/tester/seed-data/authored/content-discovery__category-brand-relations.d.ts +2 -0
  108. package/dist/features/tester/seed-data/authored/content-discovery__category-brand-relations.js +149 -0
  109. package/dist/features/tester/seed-data/authored/content-discovery__coupons.d.ts +2 -0
  110. package/dist/features/tester/seed-data/authored/content-discovery__coupons.js +121 -0
  111. package/dist/features/tester/seed-data/authored/content-discovery__event-participation.d.ts +2 -0
  112. package/dist/features/tester/seed-data/authored/content-discovery__event-participation.js +207 -0
  113. package/dist/features/tester/seed-data/authored/content-discovery__events.d.ts +2 -0
  114. package/dist/features/tester/seed-data/authored/content-discovery__events.js +318 -0
  115. package/dist/features/tester/seed-data/authored/content-discovery__faq-help.d.ts +2 -0
  116. package/dist/features/tester/seed-data/authored/content-discovery__faq-help.js +65 -0
  117. package/dist/features/tester/seed-data/authored/content-discovery__notifications.d.ts +2 -0
  118. package/dist/features/tester/seed-data/authored/content-discovery__notifications.js +147 -0
  119. package/dist/features/tester/seed-data/authored/content-discovery__search.d.ts +2 -0
  120. package/dist/features/tester/seed-data/authored/content-discovery__search.js +332 -0
  121. package/dist/features/tester/seed-data/authored/cta-layout__checkout-bottom-bar.d.ts +2 -0
  122. package/dist/features/tester/seed-data/authored/cta-layout__checkout-bottom-bar.js +53 -0
  123. package/dist/features/tester/seed-data/authored/cta-layout__dialog-footers.d.ts +2 -0
  124. package/dist/features/tester/seed-data/authored/cta-layout__dialog-footers.js +52 -0
  125. package/dist/features/tester/seed-data/authored/cta-layout__editor-action-bar.d.ts +2 -0
  126. package/dist/features/tester/seed-data/authored/cta-layout__editor-action-bar.js +35 -0
  127. package/dist/features/tester/seed-data/authored/cta-layout__navbar-ctas.d.ts +2 -0
  128. package/dist/features/tester/seed-data/authored/cta-layout__navbar-ctas.js +141 -0
  129. package/dist/features/tester/seed-data/authored/cta-layout__product-bottom-bar.d.ts +2 -0
  130. package/dist/features/tester/seed-data/authored/cta-layout__product-bottom-bar.js +35 -0
  131. package/dist/features/tester/seed-data/authored/design-ux__back-to-top-button.d.ts +2 -0
  132. package/dist/features/tester/seed-data/authored/design-ux__back-to-top-button.js +95 -0
  133. package/dist/features/tester/seed-data/authored/design-ux__carousel-arrow-bounds.d.ts +2 -0
  134. package/dist/features/tester/seed-data/authored/design-ux__carousel-arrow-bounds.js +191 -0
  135. package/dist/features/tester/seed-data/authored/design-ux__dashboard-layout.d.ts +2 -0
  136. package/dist/features/tester/seed-data/authored/design-ux__dashboard-layout.js +158 -0
  137. package/dist/features/tester/seed-data/authored/design-ux__footer-theme.d.ts +2 -0
  138. package/dist/features/tester/seed-data/authored/design-ux__footer-theme.js +106 -0
  139. package/dist/features/tester/seed-data/authored/design-ux__form-validation-errors.d.ts +2 -0
  140. package/dist/features/tester/seed-data/authored/design-ux__form-validation-errors.js +88 -0
  141. package/dist/features/tester/seed-data/authored/design-ux__general-design.d.ts +2 -0
  142. package/dist/features/tester/seed-data/authored/design-ux__general-design.js +204 -0
  143. package/dist/features/tester/seed-data/authored/design-ux__hand-mode-layout.d.ts +2 -0
  144. package/dist/features/tester/seed-data/authored/design-ux__hand-mode-layout.js +301 -0
  145. package/dist/features/tester/seed-data/authored/design-ux__homepage-carousels.d.ts +2 -0
  146. package/dist/features/tester/seed-data/authored/design-ux__homepage-carousels.js +407 -0
  147. package/dist/features/tester/seed-data/authored/design-ux__status-badge-legibility.d.ts +2 -0
  148. package/dist/features/tester/seed-data/authored/design-ux__status-badge-legibility.js +214 -0
  149. package/dist/features/tester/seed-data/authored/design-ux__sticky-cta-bar.d.ts +2 -0
  150. package/dist/features/tester/seed-data/authored/design-ux__sticky-cta-bar.js +275 -0
  151. package/dist/features/tester/seed-data/authored/index.d.ts +2 -0
  152. package/dist/features/tester/seed-data/authored/index.js +237 -0
  153. package/dist/features/tester/seed-data/authored/page-wiring__data-loss.d.ts +2 -0
  154. package/dist/features/tester/seed-data/authored/page-wiring__data-loss.js +102 -0
  155. package/dist/features/tester/seed-data/authored/page-wiring__detail-pages.d.ts +2 -0
  156. package/dist/features/tester/seed-data/authored/page-wiring__detail-pages.js +50 -0
  157. package/dist/features/tester/seed-data/authored/page-wiring__drawer-pages.d.ts +2 -0
  158. package/dist/features/tester/seed-data/authored/page-wiring__drawer-pages.js +66 -0
  159. package/dist/features/tester/seed-data/authored/page-wiring__reachability.d.ts +2 -0
  160. package/dist/features/tester/seed-data/authored/page-wiring__reachability.js +115 -0
  161. package/dist/features/tester/seed-data/authored/public-pages__auth-error-pages.d.ts +2 -0
  162. package/dist/features/tester/seed-data/authored/public-pages__auth-error-pages.js +136 -0
  163. package/dist/features/tester/seed-data/authored/public-pages__bug-hunters.d.ts +2 -0
  164. package/dist/features/tester/seed-data/authored/public-pages__bug-hunters.js +69 -0
  165. package/dist/features/tester/seed-data/authored/public-pages__core-listing-pages.d.ts +2 -0
  166. package/dist/features/tester/seed-data/authored/public-pages__core-listing-pages.js +263 -0
  167. package/dist/features/tester/seed-data/authored/public-pages__help-how-it-works.d.ts +2 -0
  168. package/dist/features/tester/seed-data/authored/public-pages__help-how-it-works.js +102 -0
  169. package/dist/features/tester/seed-data/authored/public-pages__help-scams-guides-subpages.d.ts +2 -0
  170. package/dist/features/tester/seed-data/authored/public-pages__help-scams-guides-subpages.js +234 -0
  171. package/dist/features/tester/seed-data/authored/public-pages__legal-policy-pages.d.ts +2 -0
  172. package/dist/features/tester/seed-data/authored/public-pages__legal-policy-pages.js +126 -0
  173. package/dist/features/tester/seed-data/authored/public-pages__stores-sellers-directories.d.ts +2 -0
  174. package/dist/features/tester/seed-data/authored/public-pages__stores-sellers-directories.js +255 -0
  175. package/dist/features/tester/seed-data/authored/search-and-nav__employee-permissions.d.ts +2 -0
  176. package/dist/features/tester/seed-data/authored/search-and-nav__employee-permissions.js +59 -0
  177. package/dist/features/tester/seed-data/authored/search-and-nav__header-search.d.ts +2 -0
  178. package/dist/features/tester/seed-data/authored/search-and-nav__header-search.js +88 -0
  179. package/dist/features/tester/seed-data/authored/search-and-nav__settings-deep-links.d.ts +2 -0
  180. package/dist/features/tester/seed-data/authored/search-and-nav__settings-deep-links.js +51 -0
  181. package/dist/features/tester/seed-data/authored/search-and-nav__sidebar-search.d.ts +2 -0
  182. package/dist/features/tester/seed-data/authored/search-and-nav__sidebar-search.js +35 -0
  183. package/dist/features/tester/seed-data/authored/selling__become-seller.d.ts +2 -0
  184. package/dist/features/tester/seed-data/authored/selling__become-seller.js +94 -0
  185. package/dist/features/tester/seed-data/authored/selling__final-sale-authoring.d.ts +2 -0
  186. package/dist/features/tester/seed-data/authored/selling__final-sale-authoring.js +107 -0
  187. package/dist/features/tester/seed-data/authored/selling__listing-a-product.d.ts +2 -0
  188. package/dist/features/tester/seed-data/authored/selling__listing-a-product.js +285 -0
  189. package/dist/features/tester/seed-data/authored/selling__listing-lifecycle.d.ts +2 -0
  190. package/dist/features/tester/seed-data/authored/selling__listing-lifecycle.js +326 -0
  191. package/dist/features/tester/seed-data/authored/selling__listing-type-fields-roundtrip.d.ts +2 -0
  192. package/dist/features/tester/seed-data/authored/selling__listing-type-fields-roundtrip.js +136 -0
  193. package/dist/features/tester/seed-data/authored/selling__media-limits.d.ts +2 -0
  194. package/dist/features/tester/seed-data/authored/selling__media-limits.js +128 -0
  195. package/dist/features/tester/seed-data/authored/selling__sectionised-forms.d.ts +2 -0
  196. package/dist/features/tester/seed-data/authored/selling__sectionised-forms.js +167 -0
  197. package/dist/features/tester/seed-data/authored/selling__seller-analytics-payouts.d.ts +2 -0
  198. package/dist/features/tester/seed-data/authored/selling__seller-analytics-payouts.js +117 -0
  199. package/dist/features/tester/seed-data/authored/selling__seller-bids-bundles-filters.d.ts +2 -0
  200. package/dist/features/tester/seed-data/authored/selling__seller-bids-bundles-filters.js +88 -0
  201. package/dist/features/tester/seed-data/authored/selling__seller-catalog-org.d.ts +2 -0
  202. package/dist/features/tester/seed-data/authored/selling__seller-catalog-org.js +151 -0
  203. package/dist/features/tester/seed-data/authored/selling__seller-custom-brands.d.ts +2 -0
  204. package/dist/features/tester/seed-data/authored/selling__seller-custom-brands.js +105 -0
  205. package/dist/features/tester/seed-data/authored/selling__seller-guide.d.ts +2 -0
  206. package/dist/features/tester/seed-data/authored/selling__seller-guide.js +33 -0
  207. package/dist/features/tester/seed-data/authored/selling__seller-listing-types.d.ts +2 -0
  208. package/dist/features/tester/seed-data/authored/selling__seller-listing-types.js +347 -0
  209. package/dist/features/tester/seed-data/authored/selling__seller-marketing-extras.d.ts +2 -0
  210. package/dist/features/tester/seed-data/authored/selling__seller-marketing-extras.js +166 -0
  211. package/dist/features/tester/seed-data/authored/selling__seller-ops-comms.d.ts +2 -0
  212. package/dist/features/tester/seed-data/authored/selling__seller-ops-comms.js +89 -0
  213. package/dist/features/tester/seed-data/authored/selling__seller-orders.d.ts +2 -0
  214. package/dist/features/tester/seed-data/authored/selling__seller-orders.js +195 -0
  215. package/dist/features/tester/seed-data/authored/selling__seller-shipping-payouts-setup.d.ts +2 -0
  216. package/dist/features/tester/seed-data/authored/selling__seller-shipping-payouts-setup.js +180 -0
  217. package/dist/features/tester/seed-data/authored/selling__store-dashboard-navigation.d.ts +2 -0
  218. package/dist/features/tester/seed-data/authored/selling__store-dashboard-navigation.js +164 -0
  219. package/dist/features/tester/seed-data/authored/selling__store-uncovered-pages.d.ts +2 -0
  220. package/dist/features/tester/seed-data/authored/selling__store-uncovered-pages.js +116 -0
  221. package/dist/features/tester/seed-data/authored/seo__canonical-and-host.d.ts +2 -0
  222. package/dist/features/tester/seed-data/authored/seo__canonical-and-host.js +111 -0
  223. package/dist/features/tester/seed-data/authored/seo__og-images.d.ts +2 -0
  224. package/dist/features/tester/seed-data/authored/seo__og-images.js +91 -0
  225. package/dist/features/tester/seed-data/authored/seo__page-metadata.d.ts +2 -0
  226. package/dist/features/tester/seed-data/authored/seo__page-metadata.js +122 -0
  227. package/dist/features/tester/seed-data/authored/seo__sitemap-and-robots.d.ts +2 -0
  228. package/dist/features/tester/seed-data/authored/seo__sitemap-and-robots.js +105 -0
  229. package/dist/features/tester/seed-data/carts-tester-seed-data.d.ts +3 -0
  230. package/dist/features/tester/seed-data/carts-tester-seed-data.js +70 -0
  231. package/dist/features/tester/seed-data/index.d.ts +1 -0
  232. package/dist/features/tester/seed-data/index.js +1 -0
  233. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +744 -1
  234. package/dist/seed/carousel-slides-seed-data.js +1 -1
  235. package/dist/seed/cart-seed-data.js +11 -0
  236. package/dist/seed/index.d.ts +1 -1
  237. package/dist/seed/index.js +1 -1
  238. package/dist/seed/manifest.js +2 -2
  239. package/dist/seed/notifications-seed-data.js +5 -1
  240. package/dist/seed/products-standard-seed-data.js +2 -2
  241. package/dist/seed/reviews-seed-data.js +6 -1
  242. package/package.json +1 -1
  243. package/scripts/seed-cli.mjs +752 -746
@@ -0,0 +1,344 @@
1
+ /*
2
+ * WHY: Authored six-part procedures for the buying/wishlist-history page.
3
+ * WHAT: 20 case(s), keyed by full checklist id.
4
+ *
5
+ * Written by hand, case by case, against the label each one states. There is no
6
+ * generator: the authoring scripts were deleted once it was clear they were
7
+ * scaffolding around work that is simply writing.
8
+ *
9
+ * 🛑 THE TWO CAPS BEHAVE DIFFERENTLY ON PURPOSE. The wishlist is a HARD cap of 20
10
+ * — the twenty-first add is refused with an error, because silently dropping an
11
+ * item the buyer asked to save is worse than telling them the list is full. History
12
+ * is a SOFT cap of 50 with silent oldest-first eviction, because nobody asked for
13
+ * a browsing record and an error about it would be noise.
14
+ *
15
+ * Both are one document per user, keyed on the user's own id, and every mutation
16
+ * runs in a transaction — two quick taps must not race into a duplicate.
17
+ *
18
+ * @tag domain:tester
19
+ * @tag layer:seed
20
+ * @tag pattern:none
21
+ * @tag access:server-only
22
+ * @tag consumers:seed-data/authored/index.ts
23
+ * @tag sideEffects:none
24
+ */
25
+ export const authored = {
26
+ "checklist-buying-wishlist-history-add-wishlist-pdp": {
27
+ roles: ["buyer"],
28
+ startPage: "/products/product-beyblade-burst-valkyrie",
29
+ steps: [
30
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
31
+ "Open /products/product-beyblade-burst-valkyrie and read the wishlist control's state.",
32
+ "Click it and watch the control while the request runs.",
33
+ "Read its state afterwards.",
34
+ "Open /wishlist and find the item.",
35
+ "Return to the product page and reload it, then read the control again.",
36
+ ],
37
+ inputs: { productId: "product-beyblade-burst-valkyrie" },
38
+ expectedBehaviour: "The control adds the item and then reflects that it is saved. It must also reflect the saved state on a fresh load — a control that resets to unsaved on reload is reading nothing and will let the buyer add the same item twice.",
39
+ expectedUiState: "The control changes to a saved state without a full page load, the item appears on /wishlist, and after the reload the control still reads as saved.",
40
+ endResult: "The item is on the wishlist. Later cases in this page read it.",
41
+ },
42
+ "checklist-buying-wishlist-history-add-wishlist-card": {
43
+ roles: ["buyer"],
44
+ startPage: "/products",
45
+ steps: [
46
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
47
+ "Open /products and find a product card with a wishlist control.",
48
+ "Click the wishlist control on the card WITHOUT opening the product.",
49
+ "Read the control's state and check the page did not navigate.",
50
+ "Click the card's body and check it opens that product.",
51
+ "Go back and check the card's control still reads as saved.",
52
+ ],
53
+ expectedBehaviour: "The card's wishlist control acts in place and does not navigate. Clicking the card body still opens the product — merely wiring a control onto a card must not disable its navigation, which is a defect this codebase has had where a selection callback silently removed the link.",
54
+ expectedUiState: "The control saves without navigating, and the card body still opens the product afterwards. A card that stops opening once it carries a control is the failure.",
55
+ endResult: "A second item is on the wishlist.",
56
+ },
57
+ "checklist-buying-wishlist-history-remove-wishlist": {
58
+ roles: ["buyer"],
59
+ startPage: "/wishlist",
60
+ steps: [
61
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
62
+ "Open /wishlist and note how many items it holds.",
63
+ "Remove one item and read what happens.",
64
+ "RELOAD and count the items.",
65
+ "Open that product's page and read its wishlist control.",
66
+ "Remove an item from the product page instead and check /wishlist reflects it.",
67
+ ],
68
+ expectedBehaviour: "Removal persists and both surfaces agree, because both read the same single document. A removal that succeeds on one surface and leaves the other showing the item means one of them is holding its own copy.",
69
+ expectedUiState: "The count falls by one and stays after the reload. The product page's control reads as unsaved. Removing from the product page removes it from /wishlist too.",
70
+ endResult: "One item remains on the wishlist.",
71
+ },
72
+ "checklist-buying-wishlist-history-wishlist-persists-guest-to-login": {
73
+ roles: ["guest", "buyer"],
74
+ startPage: "/products",
75
+ steps: [
76
+ "Open /products in a private window with no session.",
77
+ "Add two products to the wishlist as a guest and note their titles.",
78
+ "Open /wishlist and confirm both are listed.",
79
+ "Sign in as karthik.new@gmail.com / TempPass123! from that same window.",
80
+ "Open /wishlist and read what is listed.",
81
+ "Check both guest items are present alongside anything the account already had.",
82
+ "Reload and confirm they persist.",
83
+ ],
84
+ expectedBehaviour: "A guest wishlist is merged into the account on sign-in rather than discarded. The buyer saved those items deliberately, so losing them at the moment they create an account is the worst possible time to lose them.",
85
+ expectedUiState: "After signing in both guest items are on the account's wishlist, together with anything it already held, and they survive a reload. An emptied wishlist after sign-in is the failure.",
86
+ endResult: "The account's wishlist holds the merged set. Remove the added items afterwards.",
87
+ },
88
+ "checklist-buying-wishlist-history-wishlist-idempotent-readd": {
89
+ roles: ["buyer"],
90
+ startPage: "/products/product-beyblade-x-wizard-arrow",
91
+ steps: [
92
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
93
+ "Open /products/product-beyblade-x-wizard-arrow and add it to the wishlist.",
94
+ "Open /wishlist and count how many times it appears.",
95
+ "Return to the product and click the wishlist control twice in quick succession.",
96
+ "Open /wishlist and count again.",
97
+ "Reload and count once more.",
98
+ ],
99
+ inputs: { productId: "product-beyblade-x-wizard-arrow" },
100
+ expectedBehaviour: "Re-adding an item already saved is a no-op rather than a duplicate. Every mutation runs in a transaction precisely so two quick taps cannot race into two entries — a duplicate would also consume one of the twenty slots.",
101
+ expectedUiState: "The item appears exactly once however many times the control is pressed. Two entries for one product is the failure, and it is easiest to produce with a double tap.",
102
+ expectedData: { entriesForProduct: 1 },
103
+ endResult: "The item is on the wishlist once.",
104
+ },
105
+ "checklist-buying-wishlist-history-wishlist-cap-enforced": {
106
+ roles: ["buyer"],
107
+ startPage: "/products",
108
+ steps: [
109
+ "Sign in as karthik.new@gmail.com / TempPass123!, an account with a near-empty wishlist.",
110
+ "Open /products and add items to the wishlist until twenty are saved, counting as you go.",
111
+ "Open /wishlist and confirm the count is twenty.",
112
+ "Add a twenty-first item and read exactly what happens.",
113
+ "Open /wishlist and count again.",
114
+ "Remove one item, then add the refused item again and check it is accepted.",
115
+ ],
116
+ inputs: { cap: 20 },
117
+ expectedBehaviour: "The wishlist is a HARD cap: the twenty-first add is refused with a readable error. Silently dropping an item the buyer explicitly asked to save is worse than telling them the list is full — which is the opposite choice from history, where eviction is silent on purpose.",
118
+ expectedUiState: "The twentieth add succeeds. The twenty-first is refused with a message naming the limit, and the count stays at twenty. Freeing a slot lets the refused item in. A silent failure, or a list that grows to twenty-one, are both failures.",
119
+ expectedData: { maxItems: 20 },
120
+ endResult: "The wishlist is at or below twenty. Clear the added items afterwards.",
121
+ },
122
+ "checklist-buying-wishlist-history-wishlist-across-listing-types": {
123
+ roles: ["buyer"],
124
+ startPage: "/products",
125
+ steps: [
126
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
127
+ "Add a standard product to the wishlist.",
128
+ "Open an auction and add it.",
129
+ "Open a pre-order and add it.",
130
+ "Open a prize draw, a classified, a digital code, a live item and an art print, adding each.",
131
+ "Open /wishlist and read every entry.",
132
+ "Check each shows the right type badge and links to the right detail route.",
133
+ ],
134
+ expectedBehaviour: "Every listing type can be saved and each entry links to its own detail route. Three types once had their detail route hardcoded to the standard product page, so a saved classified, digital code or live item opened the wrong page from every card and carousel in the app.",
135
+ expectedUiState: "All eight entries are listed with the correct type badge, and each opens its own detail route rather than a /products URL. An auction entry opening /products is the wrong-route failure.",
136
+ expectedData: { wrongDetailRoutes: 0 },
137
+ endResult: "Eight items are saved. Remove them afterwards so the cap cases start clean.",
138
+ },
139
+ "checklist-buying-wishlist-history-wishlist-price-drop-accuracy": {
140
+ roles: ["buyer", "seller"],
141
+ startPage: "/wishlist",
142
+ steps: [
143
+ "Sign in as rehan.sheikh@gmail.com / TempPass123! and add product-beyblade-burst-valkyrie to the wishlist.",
144
+ "Open /wishlist and read the price shown against it.",
145
+ "Sign out and sign in as tyson@beybladearena.in / TempPass123!.",
146
+ "Lower that product's price to 799 and save.",
147
+ "Sign back in as the buyer and open /wishlist.",
148
+ "Read the price shown and any price-drop indicator.",
149
+ "Restore the product's original price.",
150
+ ],
151
+ inputs: { productId: "product-beyblade-burst-valkyrie", priceBefore: 999, priceAfter: 799 },
152
+ expectedBehaviour: "The entry records the price at the time it was saved, so a drop can be computed against it. The CURRENT price must come from the product rather than the snapshot — a list rendering the saved price as if it were live tells the buyer an item costs what it used to.",
153
+ expectedUiState: "The current price reads ₹799.00 and any drop indicator compares it against the ₹999.00 saved at add time. A list still showing ₹999.00 is reading the snapshot as live.",
154
+ expectedData: { currentPrice: 799, priceAtAdd: 999 },
155
+ endResult: "The product's price is restored. The wishlist should then show ₹999.00 again with no drop.",
156
+ },
157
+ "checklist-buying-wishlist-history-wishlist-sold-out-item": {
158
+ roles: ["buyer"],
159
+ startPage: "/wishlist",
160
+ steps: [
161
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
162
+ "Add product-beyblade-burst-valtryek-v3-sold-out to the wishlist.",
163
+ "Open /wishlist and read that entry.",
164
+ "Check it is marked as unavailable rather than looking purchasable.",
165
+ "Read whether an add-to-cart control is offered on it.",
166
+ "Click the entry and check the product page also reads as out of stock.",
167
+ ],
168
+ inputs: { productId: "product-beyblade-burst-valtryek-v3-sold-out" },
169
+ expectedBehaviour: "A saved item that has since sold out is marked as such and offers no purchase control. The wishlist is one of the few surfaces where an unavailable item legitimately remains visible — the buyer asked to watch it — so it must say so rather than being filtered away or shown as buyable.",
170
+ expectedUiState: "The entry is present and marked unavailable, with no add-to-cart control. An entry offering purchase on a sold-out item is the failure; silently removing it from the list is a different one.",
171
+ endResult: "Remove the entry afterwards.",
172
+ },
173
+ "checklist-buying-wishlist-history-wishlist-empty-state": {
174
+ roles: ["buyer"],
175
+ startPage: "/wishlist",
176
+ steps: [
177
+ "Sign in as karthik.new@gmail.com / TempPass123!.",
178
+ "Open /wishlist and remove every item until none remain.",
179
+ "Read what the page shows.",
180
+ "Check it offers a way onward rather than only stating the list is empty.",
181
+ "Follow that link and read where it lands.",
182
+ "Reload /wishlist and confirm the empty state is still shown.",
183
+ ],
184
+ expectedBehaviour: "An empty wishlist shows a named empty state with a route back into browsing. A blank area reads as a broken page rather than an empty one, and this page is reachable from the header on every visit.",
185
+ expectedUiState: "A readable message and a working link to browse. Not a bare white area and not a heading with nothing under it. The link lands on a real listing page.",
186
+ endResult: "The wishlist is empty.",
187
+ },
188
+ "checklist-buying-wishlist-history-wishlist-add-to-cart-from-list": {
189
+ roles: ["buyer"],
190
+ startPage: "/wishlist",
191
+ steps: [
192
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
193
+ "Add product-beyblade-burst-valkyrie to the wishlist and open /wishlist.",
194
+ "Use the add-to-cart control on that entry.",
195
+ "Watch the control while the request runs and read the cart badge.",
196
+ "Open /cart and confirm the item is there at the right price.",
197
+ "Return to /wishlist and read whether the item is still saved.",
198
+ ],
199
+ expectedBehaviour: "Adding to the cart from the wishlist does not remove it from the wishlist — those are two different intentions, and a buyer who adds one of several saved items has not stopped watching it. The price charged comes from the product, not from the saved snapshot.",
200
+ expectedUiState: "The cart badge increases and /cart holds the item at its current price. The wishlist entry is still present afterwards. An entry that vanishes on add-to-cart is the failure.",
201
+ endResult: "The item is in both the cart and the wishlist. Empty the cart afterwards.",
202
+ },
203
+ "checklist-buying-wishlist-history-wishlist-card-clickable": {
204
+ roles: ["buyer"],
205
+ startPage: "/wishlist",
206
+ steps: [
207
+ "Sign in as rehan.sheikh@gmail.com / TempPass123! with at least two items saved.",
208
+ "Open /wishlist and click an entry's image.",
209
+ "Read where it lands and go back.",
210
+ "Click the entry's title and read where it lands.",
211
+ "Go back and click an empty part of the entry's body.",
212
+ "Check every route reached is that item's own detail page.",
213
+ ],
214
+ expectedBehaviour: "The whole entry is a link to its item. A card that only responds on its title forces the buyer to aim, and a card that responds nowhere is a dead end — this list exists to get back to saved items.",
215
+ expectedUiState: "Image, title and body all open the same product's detail page. An inert region on the card is the finding.",
216
+ endResult: "Read-only; nothing persists.",
217
+ },
218
+ "checklist-buying-wishlist-history-wishlist-heart-solid-red": {
219
+ roles: ["buyer"],
220
+ startPage: "/products/product-beyblade-burst-valkyrie",
221
+ steps: [
222
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
223
+ "Open a product NOT on the wishlist and look at its wishlist control.",
224
+ "Note the glyph's shape and fill.",
225
+ "Add it and look at the control again.",
226
+ "Compare the saved and unsaved states — check they differ by more than colour alone.",
227
+ "Switch to dark mode and read both states again.",
228
+ "Check the glyph is a rendered icon rather than a text character.",
229
+ ],
230
+ expectedBehaviour: "Saved and unsaved are visually distinct in both themes, and the glyph is a real icon rather than a text character. A text character cannot be sized by any utility — it renders at the platform font's fallback size, which is exactly why one control in a row can look wrong beside its neighbours.",
231
+ expectedUiState: "The unsaved state is an outline and the saved state is filled, distinguishable in both themes. The glyph is proportionate to its control. A heart character used as the icon, or a state difference carried by colour alone, are both findings.",
232
+ endResult: "Remove the item afterwards.",
233
+ },
234
+ "checklist-buying-wishlist-history-wishlist-view-remove-buttons": {
235
+ roles: ["buyer"],
236
+ startPage: "/wishlist",
237
+ steps: [
238
+ "Sign in as rehan.sheikh@gmail.com / TempPass123! with at least two items saved.",
239
+ "Open /wishlist and read every control offered on an entry.",
240
+ "Check both a view and a remove control are present.",
241
+ "Use remove and read whether it asks for confirmation.",
242
+ "Read the entry count immediately and after a RELOAD.",
243
+ "Check the remove acted on the entry it was pressed on, not another.",
244
+ ],
245
+ expectedBehaviour: "Each entry offers both a way in and a way out. Remove acts on the entry it belongs to — a remove keyed on array position deletes the wrong one once the list has shifted, and both survivors still look like valid entries.",
246
+ expectedUiState: "View and remove are both present. The removed entry is the one whose control was pressed, and the count is correct after the reload.",
247
+ endResult: "One fewer item is saved.",
248
+ },
249
+ "checklist-buying-wishlist-history-wishlist-sync-item": {
250
+ roles: ["buyer"],
251
+ startPage: "/wishlist",
252
+ steps: [
253
+ "Sign in as rehan.sheikh@gmail.com / TempPass123! in window A and open /wishlist.",
254
+ "In window B, sign in as the same account and open a product not yet saved.",
255
+ "Add it to the wishlist in window B.",
256
+ "Return to window A and reload /wishlist.",
257
+ "Read whether the new item is present.",
258
+ "Remove it in window A, then reload window B's product page and read its control.",
259
+ ],
260
+ expectedBehaviour: "Both windows read one document, so a change in either is visible in the other after a reload. Whether it propagates without a reload is worth recording but is not the assertion — the wishlist is not a realtime surface.",
261
+ expectedUiState: "After the reload each window reflects the other's change. Note whether anything updated without reloading. A change that never appears even after a reload means one window is holding a private copy.",
262
+ endResult: "Both windows agree on the wishlist's contents.",
263
+ },
264
+ "checklist-buying-wishlist-history-wishlist-sync-all": {
265
+ roles: ["buyer"],
266
+ startPage: "/wishlist",
267
+ steps: [
268
+ "Sign in as rehan.sheikh@gmail.com / TempPass123! and open /wishlist.",
269
+ "Look for a control that syncs or refreshes the whole list.",
270
+ "Note the item count and each entry's price and availability.",
271
+ "Use the sync control if one exists.",
272
+ "Read whether prices and availability updated.",
273
+ "Reload the page and compare against what the sync produced.",
274
+ ],
275
+ expectedBehaviour: "A sync refreshes each entry's live price and availability from its product rather than from the saved snapshot. If no such control exists, the page must already be reading live values on load — one of the two has to be true, and this case establishes which.",
276
+ expectedUiState: "Prices and availability match the products' current values, either after the sync or already on load. Record which mechanism is in play. Values matching the saved snapshot rather than the product is the failure either way.",
277
+ endResult: "Read-only; nothing persists.",
278
+ },
279
+ "checklist-buying-wishlist-history-view-history": {
280
+ roles: ["buyer"],
281
+ startPage: "/user/history",
282
+ steps: [
283
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
284
+ "Open three different product pages in sequence, noting their titles and the order.",
285
+ "Open the browsing history page.",
286
+ "Read the entries and their order.",
287
+ "Check the most recently viewed is first.",
288
+ "Check each entry shows a title, an image and a viewed time, and links to its product.",
289
+ ],
290
+ expectedBehaviour: "History records each view with a timestamp and shows the most recent first. Each entry carries a snapshot of the product's title and image so the list renders even if the product is later removed — which is why a deleted product leaves a readable entry whose link 404s rather than a blank row.",
291
+ expectedUiState: "The three products appear newest first with titles, images and times, each linking to its product. An entry with no title or image is reading the live product rather than its snapshot.",
292
+ endResult: "Three entries are recorded.",
293
+ },
294
+ "checklist-buying-wishlist-history-history-revisit-reorders": {
295
+ roles: ["buyer"],
296
+ startPage: "/user/history",
297
+ steps: [
298
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
299
+ "Open the history page and note which product is third from the top.",
300
+ "Open that product's page again.",
301
+ "Return to the history page and read the order.",
302
+ "Check that product is now first.",
303
+ "Count the entries and check the product appears only once.",
304
+ ],
305
+ expectedBehaviour: "Revisiting a product moves its entry to the top rather than adding a second one. The existing entry for that product is removed and a fresh one inserted at the front — so the count is unchanged and the order reflects the newest visit.",
306
+ expectedUiState: "The revisited product is first and appears exactly once. The total entry count is unchanged. Two entries for one product is the failure.",
307
+ expectedData: { entriesForProduct: 1 },
308
+ endResult: "History is reordered with no duplicates.",
309
+ },
310
+ "checklist-buying-wishlist-history-history-fifo-cap": {
311
+ roles: ["buyer"],
312
+ startPage: "/user/history",
313
+ steps: [
314
+ "Sign in as karthik.new@gmail.com / TempPass123!, an account with little history.",
315
+ "Open the history page and note the entry count.",
316
+ "Browse enough distinct product pages to exceed fifty entries in total, noting the FIRST product viewed.",
317
+ "Open the history page and count the entries.",
318
+ "Look for that first product in the list.",
319
+ "Check no error or warning appeared while browsing.",
320
+ ],
321
+ inputs: { cap: 50 },
322
+ expectedBehaviour: "History is a SOFT cap: at fifty entries the oldest is evicted silently. Nobody asked for a browsing record, so an error about it would be noise — which is the opposite choice from the wishlist, where the buyer explicitly asked to save something and a silent drop would be wrong.",
323
+ expectedUiState: "The count never exceeds fifty. The earliest product viewed is gone from the list. No error or warning appeared at any point. A count above fifty means the cap is not applied on write and the document grows without bound.",
324
+ expectedData: { maxEntries: 50 },
325
+ endResult: "History holds at most fifty entries. The contrast with the wishlist's hard cap is the point.",
326
+ },
327
+ "checklist-buying-wishlist-history-history-guest-merge-on-login": {
328
+ roles: ["guest", "buyer"],
329
+ startPage: "/products",
330
+ steps: [
331
+ "Open a private window with no session and view three product pages, noting their titles.",
332
+ "Open the history page as a guest and confirm the three are listed.",
333
+ "Sign in as karthik.new@gmail.com / TempPass123! from that same window.",
334
+ "Open the history page and read the entries.",
335
+ "Check the three guest views are present alongside the account's existing history.",
336
+ "Check no product appears twice and the total does not exceed fifty.",
337
+ "Check the order is newest-first across both sets.",
338
+ ],
339
+ expectedBehaviour: "Guest history is mirrored locally and merged into the account on sign-in, de-duplicated by product with the newer view winning, and trimmed to fifty. All three of those steps matter: a merge without de-duplication produces two entries for a product seen in both states, and one without trimming pushes the document past its cap.",
340
+ expectedUiState: "All three guest products are present, no product appears twice, the total is at most fifty, and the order is newest-first across the merged set.",
341
+ expectedData: { maxEntries: 50, duplicateProducts: 0 },
342
+ endResult: "The account's history holds the merged, de-duplicated set.",
343
+ },
344
+ };
@@ -0,0 +1,2 @@
1
+ import type { AuthoredCase } from "./_types";
2
+ export declare const authored: Record<string, AuthoredCase>;
@@ -0,0 +1,53 @@
1
+ /*
2
+ * WHY: Authored six-part procedures for the community-support/public-profile page.
3
+ * WHAT: 2 case(s), keyed by full checklist id.
4
+ *
5
+ * Written by hand, case by case, against the label each one states. There is no
6
+ * generator: the authoring scripts were deleted once it was clear they were
7
+ * scaffolding around work that is simply writing.
8
+ *
9
+ * Both cases are run SIGNED OUT on purpose. A public page read while signed in as
10
+ * the owner proves nothing about what the public sees, and the store page is one
11
+ * of the surfaces that once passed a raw store document straight into a client
12
+ * component — publishing a decrypted WhatsApp token into the page HTML.
13
+ *
14
+ * @tag domain:tester
15
+ * @tag layer:seed
16
+ * @tag pattern:none
17
+ * @tag access:server-only
18
+ * @tag consumers:seed-data/authored/index.ts
19
+ * @tag sideEffects:none
20
+ */
21
+ export const authored = {
22
+ "checklist-community-support-public-profile-view-seller-store": {
23
+ roles: ["guest"],
24
+ startPage: "/stores",
25
+ steps: [
26
+ "Open /stores in a private window with no session.",
27
+ "Click the 'Beyblade Arena' card.",
28
+ "Read the store header — name, logo, banner, verified badge and rating.",
29
+ "Read the tab bar and open each tab in turn.",
30
+ "Open the browser's View Source and search the HTML for the words accessToken, adminNotes, suspensionReason and customCommissionRate.",
31
+ ],
32
+ inputs: { storeId: "store-beyblade-arena" },
33
+ expectedBehaviour: "The public store page is built from a projection that names every field it emits, rather than by spreading the store document and deleting a few keys. A deny-list is blind to fields nobody thought to delete — and to fields the TypeScript interface never declared at all.",
34
+ expectedUiState: "The header shows 'Beyblade Arena' with its logo and banner. The tabs render their listings. None of accessToken, adminNotes, suspensionReason or customCommissionRate appears anywhere in the page source, including inside the React data payload embedded at the bottom of the HTML.",
35
+ expectedData: { secretFieldsInHtml: 0 },
36
+ endResult: "Nothing persists — read-only. A hit on any of those four words is a data leak and fails the case outright, regardless of how the page looks.",
37
+ },
38
+ "checklist-community-support-public-profile-view-public-profile": {
39
+ roles: ["guest"],
40
+ startPage: "/profile/user-tyson-blader",
41
+ steps: [
42
+ "Open /profile/user-tyson-blader in a private window with no session.",
43
+ "Read the display name, avatar and bio.",
44
+ "Open each tab on the profile.",
45
+ "Search the page source for an email address and for a phone number.",
46
+ "Open /profile/user-yugi-muto and read the same things.",
47
+ ],
48
+ inputs: { sellerProfile: "user-tyson-blader", buyerProfile: "user-yugi-muto" },
49
+ expectedBehaviour: "A public profile shows what its owner chose to publish and nothing drawn from their account record. Email and phone are PII-encrypted at rest and have no business on this page in any form, masked or otherwise.",
50
+ expectedUiState: "Both profiles render a display name, avatar and bio, with their tabs populated. Neither page — nor its source — contains an email address or a phone number. A profile set to Private returns a not-found page for a signed-out visitor rather than rendering with fields blanked out.",
51
+ endResult: "Nothing persists — read-only. Both profiles are public in the seed, so a not-found here means the visibility default changed.",
52
+ },
53
+ };
@@ -0,0 +1,2 @@
1
+ import type { AuthoredCase } from "./_types";
2
+ export declare const authored: Record<string, AuthoredCase>;
@@ -0,0 +1,76 @@
1
+ /*
2
+ * WHY: Authored six-part procedures for the community-support/support-tickets page.
3
+ * WHAT: 3 case(s), keyed by full checklist id.
4
+ *
5
+ * Written by hand, case by case, against the label each one states. There is no
6
+ * generator: the authoring scripts were deleted once it was clear they were
7
+ * scaffolding around work that is simply writing.
8
+ *
9
+ * @tag domain:tester
10
+ * @tag layer:seed
11
+ * @tag pattern:none
12
+ * @tag access:server-only
13
+ * @tag consumers:seed-data/authored/index.ts
14
+ * @tag sideEffects:none
15
+ */
16
+ export const authored = {
17
+ "checklist-community-support-support-tickets-create-ticket": {
18
+ roles: ["buyer"],
19
+ startPage: "/user/support",
20
+ steps: [
21
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
22
+ "Open /user/support.",
23
+ "Click the control that starts a new ticket.",
24
+ "Type 'QA Ticket create-ticket' in the subject field.",
25
+ "Select 'Orders' as the category.",
26
+ "Type 'Raised by the tester checklist to confirm ticket creation persists.' in the message field.",
27
+ "Submit the ticket.",
28
+ "Reload /user/support.",
29
+ ],
30
+ inputs: {
31
+ subject: "QA Ticket create-ticket",
32
+ category: "Orders",
33
+ message: "Raised by the tester checklist to confirm ticket creation persists.",
34
+ },
35
+ expectedBehaviour: "A ticket document is created against this buyer with a ticket- prefixed id, an open status, and the first message stored as its opening entry rather than as a separate field the reply thread cannot see.",
36
+ expectedUiState: "The list gains a row reading 'QA Ticket create-ticket' with an open status and the Orders category. Opening it shows the submitted message as the first entry in the thread.",
37
+ expectedData: { subject: "QA Ticket create-ticket", status: "open" },
38
+ endResult: "The row is still there after the reload. A ticket that appears once and is gone on refresh was written to component state, not to Firestore.",
39
+ },
40
+ "checklist-community-support-support-tickets-reply-ticket": {
41
+ roles: ["buyer"],
42
+ startPage: "/user/support",
43
+ steps: [
44
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
45
+ "Open /user/support and open the ticket named 'QA Ticket create-ticket'.",
46
+ "Read how many messages the thread holds.",
47
+ "Type 'QA Reply reply-ticket — second message in the thread.' in the reply box.",
48
+ "Submit the reply.",
49
+ "Reload the page.",
50
+ ],
51
+ inputs: { reply: "QA Reply reply-ticket — second message in the thread." },
52
+ expectedBehaviour: "The reply is appended to the ticket's own message array in a transaction, so two replies sent quickly cannot overwrite one another. An ordinary reply that carries no status change costs one write and no read — the ticket is only re-read when a status accompanies the message.",
53
+ expectedUiState: "The thread gains a second entry with the typed text, attributed to the buyer and timestamped. The earlier message is still above it, unchanged. The ticket's status has not silently moved to resolved.",
54
+ expectedData: { threadMessageCount: 2 },
55
+ endResult: "Both messages survive the reload in the same order. A reply that replaces the first message rather than appending is the failure this case catches.",
56
+ },
57
+ "checklist-community-support-support-tickets-support-tickets-search-box": {
58
+ roles: ["buyer"],
59
+ startPage: "/user/support",
60
+ steps: [
61
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
62
+ "Open /user/support and read the total number of rows.",
63
+ "Type 'QA Ticket' in the search box.",
64
+ "Read the rows.",
65
+ "Clear the box and type 'zzzznope'.",
66
+ "Read the rows.",
67
+ "Clear the box, then use the status filter to select a status and read the rows.",
68
+ "Toggle 'Hide resolved/closed' and read the rows.",
69
+ ],
70
+ inputs: { matchingQuery: "QA Ticket", nonsenseQuery: "zzzznope" },
71
+ expectedBehaviour: "This list moved onto the shared listing scaffold, which supplies search over subject, id and category for free. The pre-existing status filter and the hide-resolved toggle have to keep working across that conversion — a migration that adds one affordance and quietly drops two is a net loss.",
72
+ expectedUiState: "'QA Ticket' narrows the list to matching subjects. 'zzzznope' returns an empty state, not the full list — that is the control which proves the box filters rather than decorates. The status filter changes which rows appear, and the toggle removes resolved and closed rows.",
73
+ expectedData: { nonsenseResultCount: 0 },
74
+ endResult: "Nothing persists; search and filter state live in the URL, so reloading reproduces the same narrowed list.",
75
+ },
76
+ };
@@ -0,0 +1,2 @@
1
+ import type { AuthoredCase } from "./_types";
2
+ export declare const authored: Record<string, AuthoredCase>;
@@ -0,0 +1,93 @@
1
+ /*
2
+ * WHY: Authored six-part procedures for the content-discovery/blog page.
3
+ * WHAT: 5 case(s), keyed by full checklist id.
4
+ *
5
+ * Written by hand, case by case, against the label each one states. There is no
6
+ * generator: the authoring scripts were deleted once it was clear they were
7
+ * scaffolding around work that is simply writing.
8
+ *
9
+ * Blog posts have no gallery field, so extra images live inline in the content
10
+ * HTML — a case looking for a separate image array is looking for something the
11
+ * document has never had.
12
+ *
13
+ * @tag domain:tester
14
+ * @tag layer:seed
15
+ * @tag pattern:none
16
+ * @tag access:server-only
17
+ * @tag consumers:seed-data/authored/index.ts
18
+ * @tag sideEffects:none
19
+ */
20
+ export const authored = {
21
+ "checklist-content-discovery-blog-blog-listing": {
22
+ roles: ["guest"],
23
+ startPage: "/blog",
24
+ steps: [
25
+ "Open /blog in a private window with no session.",
26
+ "Read every card — title, excerpt, cover image, category and read time.",
27
+ "Note whether any card names a draft or archived post.",
28
+ "Use the category filter, selecting each value in turn, and read the results.",
29
+ "Page to the end of the list.",
30
+ ],
31
+ expectedBehaviour: "The listing shows published posts only. The seed holds 17 published, 2 draft and 1 archived, so a listing showing 20 is not filtering by status at all — and status filtering is the kind of guard that gets dropped when a route stops sending a parameter the query only applied when asked.",
32
+ expectedUiState: "Every card carries a title, an excerpt, a rendered cover image and a category. No draft or archived post appears. Each category filter value returns rows or a named empty state.",
33
+ expectedData: { draftPostsVisible: 0 },
34
+ endResult: "Read-only; nothing persists beyond the URL.",
35
+ },
36
+ "checklist-content-discovery-blog-read-post": {
37
+ roles: ["guest"],
38
+ startPage: "/blog",
39
+ steps: [
40
+ "Open /blog in a private window and click the first post.",
41
+ "Read the title, author, publish date and read time.",
42
+ "Read the whole article body, checking the paragraphs and any inline images render.",
43
+ "Read the address bar and note whether the URL uses the post's slug.",
44
+ "Reload the page.",
45
+ ],
46
+ expectedBehaviour: "A post renders its stored HTML content, including the images embedded inline within it. The route is keyed on slug, so the URL is stable and shareable.",
47
+ expectedUiState: "Title, author, date and read time are shown. The body renders as formatted prose with its inline images displayed — not as raw HTML tags shown as visible text, and not as a wall of markup. The URL carries the post's slug.",
48
+ endResult: "Read-only; nothing persists. The reload shows the same article.",
49
+ },
50
+ "checklist-content-discovery-blog-blog-cover-image-display": {
51
+ roles: ["guest"],
52
+ startPage: "/blog",
53
+ steps: [
54
+ "Open /blog in a private window and look at every card's cover image.",
55
+ "Hard-reload with Ctrl+Shift+R and look again.",
56
+ "Open one post and look at its cover image at the top of the article.",
57
+ "Note whether the same image appears on the card and on the post.",
58
+ "Look for any broken-image glyph or grey placeholder tile.",
59
+ ],
60
+ expectedBehaviour: "Cover images are served through the media proxy, which is what applies the watermark and keeps the storage bucket private. An image stored as a raw bucket URL bypasses that entirely and is the pattern to watch for.",
61
+ expectedUiState: "Every card shows its cover image, on both loads. The post's hero image matches its card's. No broken-image glyph and no grey placeholder square anywhere.",
62
+ endResult: "Read-only; nothing persists.",
63
+ },
64
+ "checklist-content-discovery-blog-blog-youtube-embed": {
65
+ roles: ["guest"],
66
+ startPage: "/blog",
67
+ steps: [
68
+ "Open /blog in a private window and find a post whose card or body indicates a video.",
69
+ "Open that post.",
70
+ "Scroll to the embedded video.",
71
+ "Click play and watch for a few seconds.",
72
+ "Read any error text shown in or near the player.",
73
+ ],
74
+ expectedBehaviour: "A YouTube id on a post renders as a privacy-preserving embed. The failure worth naming is the one the product-detail pages had: a YouTube URL handed to a native video element, which cannot play a watch-page URL and says so in the player's own words.",
75
+ expectedUiState: "The embedded player renders and plays on click. What must not appear is 'No video with supported format and MIME type found', an empty black box, or a bare link where a player should be.",
76
+ endResult: "Read-only; nothing persists.",
77
+ },
78
+ "checklist-content-discovery-blog-blog-related-posts-sections": {
79
+ roles: ["guest"],
80
+ startPage: "/blog",
81
+ steps: [
82
+ "Open /blog in a private window and open any post.",
83
+ "Scroll below the article body.",
84
+ "Read the heading of each related section and the cards inside it.",
85
+ "Check whether the post currently open appears in any of them.",
86
+ "Click a card in each section and confirm it opens that post.",
87
+ ],
88
+ expectedBehaviour: "Three separate signals are rendered below the article — same category, shared tags, and same author — each as its own section. A section with a heading and an empty rail should not render at all; showing the heading anyway advertises content that is not there.",
89
+ expectedUiState: "Three headed sections appear: Related Posts, 'You might also like', and a same-author section. Each holds at least one card with a real title and image. The current post appears in none of them, and every card opens the post it names.",
90
+ expectedData: { selfLinkCount: 0 },
91
+ endResult: "Read-only; nothing persists.",
92
+ },
93
+ };
@@ -0,0 +1,2 @@
1
+ import type { AuthoredCase } from "./_types";
2
+ export declare const authored: Record<string, AuthoredCase>;