@ultracart/bq-skill 0.1.2

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 (303) hide show
  1. package/LICENSE +191 -0
  2. package/README.md +952 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +42 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/alarm.d.ts +3 -0
  8. package/dist/commands/alarm.d.ts.map +1 -0
  9. package/dist/commands/alarm.js +146 -0
  10. package/dist/commands/alarm.js.map +1 -0
  11. package/dist/commands/config.d.ts +3 -0
  12. package/dist/commands/config.d.ts.map +1 -0
  13. package/dist/commands/config.js +749 -0
  14. package/dist/commands/config.js.map +1 -0
  15. package/dist/commands/deck.d.ts +3 -0
  16. package/dist/commands/deck.d.ts.map +1 -0
  17. package/dist/commands/deck.js +567 -0
  18. package/dist/commands/deck.js.map +1 -0
  19. package/dist/commands/dry-run.d.ts +3 -0
  20. package/dist/commands/dry-run.d.ts.map +1 -0
  21. package/dist/commands/dry-run.js +105 -0
  22. package/dist/commands/dry-run.js.map +1 -0
  23. package/dist/commands/history.d.ts +3 -0
  24. package/dist/commands/history.d.ts.map +1 -0
  25. package/dist/commands/history.js +127 -0
  26. package/dist/commands/history.js.map +1 -0
  27. package/dist/commands/init.d.ts +3 -0
  28. package/dist/commands/init.d.ts.map +1 -0
  29. package/dist/commands/init.js +302 -0
  30. package/dist/commands/init.js.map +1 -0
  31. package/dist/commands/install-skill.d.ts +3 -0
  32. package/dist/commands/install-skill.d.ts.map +1 -0
  33. package/dist/commands/install-skill.js +132 -0
  34. package/dist/commands/install-skill.js.map +1 -0
  35. package/dist/commands/list.d.ts +3 -0
  36. package/dist/commands/list.d.ts.map +1 -0
  37. package/dist/commands/list.js +89 -0
  38. package/dist/commands/list.js.map +1 -0
  39. package/dist/commands/query.d.ts +3 -0
  40. package/dist/commands/query.d.ts.map +1 -0
  41. package/dist/commands/query.js +152 -0
  42. package/dist/commands/query.js.map +1 -0
  43. package/dist/commands/render.d.ts +3 -0
  44. package/dist/commands/render.d.ts.map +1 -0
  45. package/dist/commands/render.js +107 -0
  46. package/dist/commands/render.js.map +1 -0
  47. package/dist/commands/run-all.d.ts +3 -0
  48. package/dist/commands/run-all.d.ts.map +1 -0
  49. package/dist/commands/run-all.js +285 -0
  50. package/dist/commands/run-all.js.map +1 -0
  51. package/dist/commands/run.d.ts +3 -0
  52. package/dist/commands/run.d.ts.map +1 -0
  53. package/dist/commands/run.js +321 -0
  54. package/dist/commands/run.js.map +1 -0
  55. package/dist/commands/schema.d.ts +3 -0
  56. package/dist/commands/schema.d.ts.map +1 -0
  57. package/dist/commands/schema.js +271 -0
  58. package/dist/commands/schema.js.map +1 -0
  59. package/dist/commands/validate.d.ts +3 -0
  60. package/dist/commands/validate.d.ts.map +1 -0
  61. package/dist/commands/validate.js +109 -0
  62. package/dist/commands/validate.js.map +1 -0
  63. package/dist/lib/alarm-notify.d.ts +16 -0
  64. package/dist/lib/alarm-notify.d.ts.map +1 -0
  65. package/dist/lib/alarm-notify.js +312 -0
  66. package/dist/lib/alarm-notify.js.map +1 -0
  67. package/dist/lib/alarm-state.d.ts +26 -0
  68. package/dist/lib/alarm-state.d.ts.map +1 -0
  69. package/dist/lib/alarm-state.js +118 -0
  70. package/dist/lib/alarm-state.js.map +1 -0
  71. package/dist/lib/alarm.d.ts +28 -0
  72. package/dist/lib/alarm.d.ts.map +1 -0
  73. package/dist/lib/alarm.js +215 -0
  74. package/dist/lib/alarm.js.map +1 -0
  75. package/dist/lib/analysis.d.ts +16 -0
  76. package/dist/lib/analysis.d.ts.map +1 -0
  77. package/dist/lib/analysis.js +134 -0
  78. package/dist/lib/analysis.js.map +1 -0
  79. package/dist/lib/bigquery.d.ts +55 -0
  80. package/dist/lib/bigquery.d.ts.map +1 -0
  81. package/dist/lib/bigquery.js +321 -0
  82. package/dist/lib/bigquery.js.map +1 -0
  83. package/dist/lib/config-writer.d.ts +3 -0
  84. package/dist/lib/config-writer.d.ts.map +1 -0
  85. package/dist/lib/config-writer.js +60 -0
  86. package/dist/lib/config-writer.js.map +1 -0
  87. package/dist/lib/config.d.ts +63 -0
  88. package/dist/lib/config.d.ts.map +1 -0
  89. package/dist/lib/config.js +151 -0
  90. package/dist/lib/config.js.map +1 -0
  91. package/dist/lib/dashboard.d.ts +3 -0
  92. package/dist/lib/dashboard.d.ts.map +1 -0
  93. package/dist/lib/dashboard.js +468 -0
  94. package/dist/lib/dashboard.js.map +1 -0
  95. package/dist/lib/deck.d.ts +58 -0
  96. package/dist/lib/deck.d.ts.map +1 -0
  97. package/dist/lib/deck.js +232 -0
  98. package/dist/lib/deck.js.map +1 -0
  99. package/dist/lib/deliver-email.d.ts +14 -0
  100. package/dist/lib/deliver-email.d.ts.map +1 -0
  101. package/dist/lib/deliver-email.js +360 -0
  102. package/dist/lib/deliver-email.js.map +1 -0
  103. package/dist/lib/deliver-slack.d.ts +6 -0
  104. package/dist/lib/deliver-slack.d.ts.map +1 -0
  105. package/dist/lib/deliver-slack.js +73 -0
  106. package/dist/lib/deliver-slack.js.map +1 -0
  107. package/dist/lib/deliver.d.ts +10 -0
  108. package/dist/lib/deliver.d.ts.map +1 -0
  109. package/dist/lib/deliver.js +95 -0
  110. package/dist/lib/deliver.js.map +1 -0
  111. package/dist/lib/llm/anthropic.d.ts +7 -0
  112. package/dist/lib/llm/anthropic.d.ts.map +1 -0
  113. package/dist/lib/llm/anthropic.js +69 -0
  114. package/dist/lib/llm/anthropic.js.map +1 -0
  115. package/dist/lib/llm/bedrock.d.ts +7 -0
  116. package/dist/lib/llm/bedrock.d.ts.map +1 -0
  117. package/dist/lib/llm/bedrock.js +67 -0
  118. package/dist/lib/llm/bedrock.js.map +1 -0
  119. package/dist/lib/llm/gemini.d.ts +7 -0
  120. package/dist/lib/llm/gemini.d.ts.map +1 -0
  121. package/dist/lib/llm/gemini.js +67 -0
  122. package/dist/lib/llm/gemini.js.map +1 -0
  123. package/dist/lib/llm/index.d.ts +5 -0
  124. package/dist/lib/llm/index.d.ts.map +1 -0
  125. package/dist/lib/llm/index.js +61 -0
  126. package/dist/lib/llm/index.js.map +1 -0
  127. package/dist/lib/llm/models.d.ts +5 -0
  128. package/dist/lib/llm/models.d.ts.map +1 -0
  129. package/dist/lib/llm/models.js +33 -0
  130. package/dist/lib/llm/models.js.map +1 -0
  131. package/dist/lib/llm/openai.d.ts +8 -0
  132. package/dist/lib/llm/openai.d.ts.map +1 -0
  133. package/dist/lib/llm/openai.js +48 -0
  134. package/dist/lib/llm/openai.js.map +1 -0
  135. package/dist/lib/llm/provider.d.ts +28 -0
  136. package/dist/lib/llm/provider.d.ts.map +1 -0
  137. package/dist/lib/llm/provider.js +3 -0
  138. package/dist/lib/llm/provider.js.map +1 -0
  139. package/dist/lib/manifest.d.ts +95 -0
  140. package/dist/lib/manifest.d.ts.map +1 -0
  141. package/dist/lib/manifest.js +105 -0
  142. package/dist/lib/manifest.js.map +1 -0
  143. package/dist/lib/params.d.ts +27 -0
  144. package/dist/lib/params.d.ts.map +1 -0
  145. package/dist/lib/params.js +192 -0
  146. package/dist/lib/params.js.map +1 -0
  147. package/dist/lib/pdf.d.ts +8 -0
  148. package/dist/lib/pdf.d.ts.map +1 -0
  149. package/dist/lib/pdf.js +86 -0
  150. package/dist/lib/pdf.js.map +1 -0
  151. package/dist/lib/renderer.d.ts +17 -0
  152. package/dist/lib/renderer.d.ts.map +1 -0
  153. package/dist/lib/renderer.js +166 -0
  154. package/dist/lib/renderer.js.map +1 -0
  155. package/dist/lib/schema-filter.d.ts +3 -0
  156. package/dist/lib/schema-filter.d.ts.map +1 -0
  157. package/dist/lib/schema-filter.js +49 -0
  158. package/dist/lib/schema-filter.js.map +1 -0
  159. package/dist/lib/template.d.ts +4 -0
  160. package/dist/lib/template.d.ts.map +1 -0
  161. package/dist/lib/template.js +37 -0
  162. package/dist/lib/template.js.map +1 -0
  163. package/dist/lib/validator.d.ts +8 -0
  164. package/dist/lib/validator.d.ts.map +1 -0
  165. package/dist/lib/validator.js +88 -0
  166. package/dist/lib/validator.js.map +1 -0
  167. package/package.json +59 -0
  168. package/schemas/deck.schema.json +122 -0
  169. package/schemas/report-manifest.schema.json +309 -0
  170. package/schemas/tables/README.md +45 -0
  171. package/schemas/tables/ultracart_dw/uc_affiliate_clicks.json +186 -0
  172. package/schemas/tables/ultracart_dw/uc_affiliate_commission_groups.json +317 -0
  173. package/schemas/tables/ultracart_dw/uc_affiliate_ledgers.json +404 -0
  174. package/schemas/tables/ultracart_dw/uc_affiliate_network_pixel_postback_logs.json +166 -0
  175. package/schemas/tables/ultracart_dw/uc_affiliate_network_pixels.json +106 -0
  176. package/schemas/tables/ultracart_dw/uc_affiliate_payments.json +204 -0
  177. package/schemas/tables/ultracart_dw/uc_affiliate_postback_logs.json +90 -0
  178. package/schemas/tables/ultracart_dw/uc_affiliates.json +425 -0
  179. package/schemas/tables/ultracart_dw/uc_auto_orders.json +13848 -0
  180. package/schemas/tables/ultracart_dw/uc_cart_abandons.json +3971 -0
  181. package/schemas/tables/ultracart_dw/uc_conversation_pbx_calls.json +374 -0
  182. package/schemas/tables/ultracart_dw/uc_conversations.json +374 -0
  183. package/schemas/tables/ultracart_dw/uc_coupons.json +1893 -0
  184. package/schemas/tables/ultracart_dw/uc_customers.json +11886 -0
  185. package/schemas/tables/ultracart_dw/uc_fraud_rules.json +239 -0
  186. package/schemas/tables/ultracart_dw/uc_gift_certificates.json +135 -0
  187. package/schemas/tables/ultracart_dw/uc_item_inventory_history.json +79 -0
  188. package/schemas/tables/ultracart_dw/uc_items.json +4437 -0
  189. package/schemas/tables/ultracart_dw/uc_orders.json +6629 -0
  190. package/schemas/tables/ultracart_dw/uc_rotating_transaction_gateway_history.json +271 -0
  191. package/schemas/tables/ultracart_dw/uc_rotating_transaction_gateways.json +416 -0
  192. package/schemas/tables/ultracart_dw/uc_shipping_methods.json +1372 -0
  193. package/schemas/tables/ultracart_dw/uc_storefront_customers.json +261 -0
  194. package/schemas/tables/ultracart_dw/uc_storefront_experiments.json +386 -0
  195. package/schemas/tables/ultracart_dw/uc_storefront_pages.json +513 -0
  196. package/schemas/tables/ultracart_dw/uc_storefront_upsell_offer_events.json +338 -0
  197. package/schemas/tables/ultracart_dw/uc_storefront_upsell_offers.json +431 -0
  198. package/schemas/tables/ultracart_dw/uc_storefront_upsell_paths.json +163 -0
  199. package/schemas/tables/ultracart_dw/uc_storefronts.json +62 -0
  200. package/schemas/tables/ultracart_dw/uc_surveys.json +238 -0
  201. package/schemas/tables/ultracart_dw/uc_workflow_tasks.json +377 -0
  202. package/schemas/tables/ultracart_dw/uc_zoho_desk_tickets.json +1184 -0
  203. package/schemas/tables/ultracart_dw_high/uc_affiliate_clicks.json +186 -0
  204. package/schemas/tables/ultracart_dw_high/uc_affiliate_commission_groups.json +317 -0
  205. package/schemas/tables/ultracart_dw_high/uc_affiliate_ledgers.json +404 -0
  206. package/schemas/tables/ultracart_dw_high/uc_affiliate_network_pixel_postback_logs.json +166 -0
  207. package/schemas/tables/ultracart_dw_high/uc_affiliate_network_pixels.json +106 -0
  208. package/schemas/tables/ultracart_dw_high/uc_affiliate_payments.json +204 -0
  209. package/schemas/tables/ultracart_dw_high/uc_affiliate_postback_logs.json +90 -0
  210. package/schemas/tables/ultracart_dw_high/uc_affiliates.json +425 -0
  211. package/schemas/tables/ultracart_dw_high/uc_auto_orders.json +14332 -0
  212. package/schemas/tables/ultracart_dw_high/uc_cart_abandons.json +4245 -0
  213. package/schemas/tables/ultracart_dw_high/uc_conversation_pbx_calls.json +415 -0
  214. package/schemas/tables/ultracart_dw_high/uc_conversations.json +415 -0
  215. package/schemas/tables/ultracart_dw_high/uc_coupons.json +1893 -0
  216. package/schemas/tables/ultracart_dw_high/uc_customers.json +12250 -0
  217. package/schemas/tables/ultracart_dw_high/uc_fraud_rules.json +239 -0
  218. package/schemas/tables/ultracart_dw_high/uc_gift_certificates.json +135 -0
  219. package/schemas/tables/ultracart_dw_high/uc_item_inventory_history.json +79 -0
  220. package/schemas/tables/ultracart_dw_high/uc_items.json +4437 -0
  221. package/schemas/tables/ultracart_dw_high/uc_orders.json +6871 -0
  222. package/schemas/tables/ultracart_dw_high/uc_rotating_transaction_gateway_history.json +271 -0
  223. package/schemas/tables/ultracart_dw_high/uc_rotating_transaction_gateways.json +416 -0
  224. package/schemas/tables/ultracart_dw_high/uc_shipping_methods.json +1372 -0
  225. package/schemas/tables/ultracart_dw_high/uc_storefront_customers.json +261 -0
  226. package/schemas/tables/ultracart_dw_high/uc_storefront_experiments.json +386 -0
  227. package/schemas/tables/ultracart_dw_high/uc_storefront_pages.json +513 -0
  228. package/schemas/tables/ultracart_dw_high/uc_storefront_upsell_offer_events.json +338 -0
  229. package/schemas/tables/ultracart_dw_high/uc_storefront_upsell_offers.json +431 -0
  230. package/schemas/tables/ultracart_dw_high/uc_storefront_upsell_paths.json +163 -0
  231. package/schemas/tables/ultracart_dw_high/uc_storefronts.json +62 -0
  232. package/schemas/tables/ultracart_dw_high/uc_surveys.json +269 -0
  233. package/schemas/tables/ultracart_dw_high/uc_workflow_tasks.json +377 -0
  234. package/schemas/tables/ultracart_dw_high/uc_zoho_desk_tickets.json +1330 -0
  235. package/schemas/tables/ultracart_dw_low/uc_affiliate_clicks.json +186 -0
  236. package/schemas/tables/ultracart_dw_low/uc_affiliate_commission_groups.json +317 -0
  237. package/schemas/tables/ultracart_dw_low/uc_affiliate_ledgers.json +404 -0
  238. package/schemas/tables/ultracart_dw_low/uc_affiliate_network_pixel_postback_logs.json +166 -0
  239. package/schemas/tables/ultracart_dw_low/uc_affiliate_network_pixels.json +106 -0
  240. package/schemas/tables/ultracart_dw_low/uc_affiliate_payments.json +204 -0
  241. package/schemas/tables/ultracart_dw_low/uc_affiliate_postback_logs.json +90 -0
  242. package/schemas/tables/ultracart_dw_low/uc_affiliates.json +425 -0
  243. package/schemas/tables/ultracart_dw_low/uc_auto_orders.json +13868 -0
  244. package/schemas/tables/ultracart_dw_low/uc_cart_abandons.json +3971 -0
  245. package/schemas/tables/ultracart_dw_low/uc_conversation_pbx_calls.json +374 -0
  246. package/schemas/tables/ultracart_dw_low/uc_conversations.json +374 -0
  247. package/schemas/tables/ultracart_dw_low/uc_coupons.json +1893 -0
  248. package/schemas/tables/ultracart_dw_low/uc_customers.json +11900 -0
  249. package/schemas/tables/ultracart_dw_low/uc_fraud_rules.json +239 -0
  250. package/schemas/tables/ultracart_dw_low/uc_gift_certificates.json +135 -0
  251. package/schemas/tables/ultracart_dw_low/uc_item_inventory_history.json +79 -0
  252. package/schemas/tables/ultracart_dw_low/uc_items.json +4437 -0
  253. package/schemas/tables/ultracart_dw_low/uc_orders.json +6639 -0
  254. package/schemas/tables/ultracart_dw_low/uc_rotating_transaction_gateway_history.json +271 -0
  255. package/schemas/tables/ultracart_dw_low/uc_rotating_transaction_gateways.json +416 -0
  256. package/schemas/tables/ultracart_dw_low/uc_shipping_methods.json +1372 -0
  257. package/schemas/tables/ultracart_dw_low/uc_storefront_customers.json +261 -0
  258. package/schemas/tables/ultracart_dw_low/uc_storefront_experiments.json +386 -0
  259. package/schemas/tables/ultracart_dw_low/uc_storefront_pages.json +513 -0
  260. package/schemas/tables/ultracart_dw_low/uc_storefront_upsell_offer_events.json +338 -0
  261. package/schemas/tables/ultracart_dw_low/uc_storefront_upsell_offers.json +431 -0
  262. package/schemas/tables/ultracart_dw_low/uc_storefront_upsell_paths.json +163 -0
  263. package/schemas/tables/ultracart_dw_low/uc_storefronts.json +62 -0
  264. package/schemas/tables/ultracart_dw_low/uc_surveys.json +238 -0
  265. package/schemas/tables/ultracart_dw_low/uc_workflow_tasks.json +377 -0
  266. package/schemas/tables/ultracart_dw_low/uc_zoho_desk_tickets.json +1184 -0
  267. package/schemas/tables/ultracart_dw_medium/uc_affiliate_clicks.json +186 -0
  268. package/schemas/tables/ultracart_dw_medium/uc_affiliate_commission_groups.json +317 -0
  269. package/schemas/tables/ultracart_dw_medium/uc_affiliate_ledgers.json +404 -0
  270. package/schemas/tables/ultracart_dw_medium/uc_affiliate_network_pixel_postback_logs.json +166 -0
  271. package/schemas/tables/ultracart_dw_medium/uc_affiliate_network_pixels.json +106 -0
  272. package/schemas/tables/ultracart_dw_medium/uc_affiliate_payments.json +204 -0
  273. package/schemas/tables/ultracart_dw_medium/uc_affiliate_postback_logs.json +90 -0
  274. package/schemas/tables/ultracart_dw_medium/uc_affiliates.json +425 -0
  275. package/schemas/tables/ultracart_dw_medium/uc_auto_orders.json +14320 -0
  276. package/schemas/tables/ultracart_dw_medium/uc_cart_abandons.json +4245 -0
  277. package/schemas/tables/ultracart_dw_medium/uc_conversation_pbx_calls.json +415 -0
  278. package/schemas/tables/ultracart_dw_medium/uc_conversations.json +415 -0
  279. package/schemas/tables/ultracart_dw_medium/uc_coupons.json +1893 -0
  280. package/schemas/tables/ultracart_dw_medium/uc_customers.json +12250 -0
  281. package/schemas/tables/ultracart_dw_medium/uc_fraud_rules.json +239 -0
  282. package/schemas/tables/ultracart_dw_medium/uc_gift_certificates.json +135 -0
  283. package/schemas/tables/ultracart_dw_medium/uc_item_inventory_history.json +79 -0
  284. package/schemas/tables/ultracart_dw_medium/uc_items.json +4437 -0
  285. package/schemas/tables/ultracart_dw_medium/uc_orders.json +6865 -0
  286. package/schemas/tables/ultracart_dw_medium/uc_rotating_transaction_gateway_history.json +271 -0
  287. package/schemas/tables/ultracart_dw_medium/uc_rotating_transaction_gateways.json +416 -0
  288. package/schemas/tables/ultracart_dw_medium/uc_shipping_methods.json +1372 -0
  289. package/schemas/tables/ultracart_dw_medium/uc_storefront_customers.json +261 -0
  290. package/schemas/tables/ultracart_dw_medium/uc_storefront_experiments.json +386 -0
  291. package/schemas/tables/ultracart_dw_medium/uc_storefront_pages.json +513 -0
  292. package/schemas/tables/ultracart_dw_medium/uc_storefront_upsell_offer_events.json +338 -0
  293. package/schemas/tables/ultracart_dw_medium/uc_storefront_upsell_offers.json +431 -0
  294. package/schemas/tables/ultracart_dw_medium/uc_storefront_upsell_paths.json +163 -0
  295. package/schemas/tables/ultracart_dw_medium/uc_storefronts.json +62 -0
  296. package/schemas/tables/ultracart_dw_medium/uc_surveys.json +269 -0
  297. package/schemas/tables/ultracart_dw_medium/uc_workflow_tasks.json +377 -0
  298. package/schemas/tables/ultracart_dw_medium/uc_zoho_desk_tickets.json +1330 -0
  299. package/schemas/tables/ultracart_dw_streaming/uc_analytics_session_streaming.json +2444 -0
  300. package/schemas/tables/ultracart_dw_streaming/uc_screen_recording_streaming.json +509 -0
  301. package/schemas/ultracart-bq-config.schema.json +140 -0
  302. package/skill/skill.md +1228 -0
  303. package/templates/render.html +73 -0
package/README.md ADDED
@@ -0,0 +1,952 @@
1
+ # @ultracart/bq-skill
2
+
3
+ **Reports as code. Version-controlled, automated, and replayable — no SaaS reporting tool required.**
4
+
5
+ Your UltraCart BigQuery data warehouse already has the data. Most reporting tools make you build dashboards in a proprietary UI you can't version, can't diff, and can't automate outside their ecosystem. This package takes a different approach: reports live in your Git repo as SQL, chart configs, and YAML manifests. You get pull requests, commit history, branch-and-merge workflows, and CI/CD automation — the same infrastructure you already use for everything else.
6
+
7
+ Claude Code designs the report. After that, replay is deterministic Node.js — no per-seat licenses, no vendor lock-in. Need AI-generated executive analysis on each run? Plug in any major LLM provider (Anthropic, OpenAI, Google Gemini, Grok, AWS Bedrock) or skip it entirely and just get the charts and data.
8
+
9
+ ### Why this over a reporting tool
10
+
11
+ - **Reports are code.** SQL, chart configs, and manifests live in Git. Review changes in PRs, track history with `git log`, roll back a broken report with `git revert`. Your reporting stack gets the same rigor as your application code.
12
+ - **Design once, replay forever.** Claude Code writes the SQL, builds the chart, and saves a replayable manifest. From then on, `uc-bq run` refreshes with fresh data — optionally with AI-generated executive analysis, or charts-only with no AI cost at all. Schedule it in GitHub Actions or cron.
13
+ - **Professional output, not just dashboards.** Every report produces charts (ECharts), PDFs, executive analysis, and optional Slack/email delivery. Combine reports into branded decks or interactive HTML dashboards — delivered automatically.
14
+ - **Management by exception.** Define alarms on your metrics — revenue drops, missing data, unusual spikes. Reports run silently; you only hear about it when something needs attention.
15
+
16
+ ### How it works
17
+
18
+ 1. **Ask a question** — In Claude Code: *"Show me revenue trends by product category for the last 90 days."* Claude discovers your schema, writes optimized SQL, creates a visualization, and saves a replayable report manifest.
19
+ 2. **Replay anytime** — `uc-bq run revenue-by-category` re-executes the saved SQL, re-renders the chart, and regenerates the PDF. Add `--no-analysis` for pure data/charts, or let it call your configured LLM for fresh executive analysis.
20
+ 3. **Automate with your existing tools** — Commit reports to Git. Schedule runs in GitHub Actions. Deliver to Slack and email. Same workflow as the rest of your stack.
21
+
22
+ ## What This Is
23
+
24
+ UltraCart streams e-commerce data (orders, customers, items, analytics, etc.) into a per-merchant BigQuery data warehouse. This package gives merchants two things:
25
+
26
+ 1. **`uc-bq` CLI** — A command-line tool that handles BigQuery queries, ECharts rendering, schema validation, and report replay. No LLM needed for replay.
27
+ 2. **Claude Code skill prompt** — A comprehensive prompt that teaches Claude Code how to build reports using the CLI. Claude Code does the thinking (SQL generation, chart design, analysis), the CLI does the execution.
28
+
29
+ ## Prerequisites
30
+
31
+ - **Node.js** >= 24
32
+ - **Google Cloud credentials** — either:
33
+ - `gcloud auth application-default login` (recommended), or
34
+ - `GOOGLE_APPLICATION_CREDENTIALS` pointing to a service account JSON
35
+ - **BigQuery access** — your UltraCart merchant account must have the data warehouse enabled
36
+ - **Puppeteer** — installed automatically with the package (for headless chart rendering)
37
+ - **Claude Code** — for creating new reports (not needed for replaying existing ones)
38
+
39
+ ## Installation
40
+
41
+ ```bash
42
+ npm install -g @ultracart/bq-skill
43
+ ```
44
+
45
+ All LLM provider SDKs (Anthropic, OpenAI, Google Gemini, AWS Bedrock) are bundled — no extra installs needed.
46
+
47
+ ## Authentication
48
+
49
+ The CLI uses Google Cloud's Application Default Credentials (ADC). You authenticate once, and the BigQuery SDK picks up your credentials automatically — no tokens or keys in your code.
50
+
51
+ ### Option A: gcloud CLI (recommended for development)
52
+
53
+ This is the simplest path. You sign in with your Google account and the SDK handles the rest.
54
+
55
+ **1. Install the Google Cloud CLI** (if you don't already have it):
56
+
57
+ ```bash
58
+ # macOS
59
+ brew install google-cloud-sdk
60
+
61
+ # Linux (Debian/Ubuntu)
62
+ sudo apt-get install google-cloud-cli
63
+
64
+ # Windows
65
+ # Download from https://cloud.google.com/sdk/docs/install
66
+ ```
67
+
68
+ **2. Log in to your Google account:**
69
+
70
+ ```bash
71
+ gcloud auth login
72
+ ```
73
+
74
+ This opens a browser window. Sign in with the Google account that has access to your UltraCart BigQuery project.
75
+
76
+ **3. Set application default credentials:**
77
+
78
+ ```bash
79
+ gcloud auth application-default login
80
+ ```
81
+
82
+ This creates a local credential file that the BigQuery SDK finds automatically. You only need to do this once per machine (credentials persist across terminal sessions).
83
+
84
+ **4. Verify it works:**
85
+
86
+ ```bash
87
+ uc-bq init
88
+ # Or if you already have a config:
89
+ uc-bq schema --list
90
+ ```
91
+
92
+ If you see your tables, you're authenticated.
93
+
94
+ **Logging out:**
95
+
96
+ ```bash
97
+ # Revoke application default credentials
98
+ gcloud auth application-default revoke
99
+
100
+ # Revoke your full gcloud login
101
+ gcloud auth revoke
102
+ ```
103
+
104
+ ### Option B: Service Account (recommended for CI/CD and scheduled runs)
105
+
106
+ Use this for automated/headless environments where you can't open a browser.
107
+
108
+ **1. Create a GCP project** (if you don't have one):
109
+
110
+ Go to [Google Cloud Console](https://console.cloud.google.com/) and create a project (or use an existing one). This is YOUR project — separate from UltraCart's.
111
+
112
+ **2. Create a service account:**
113
+
114
+ ```bash
115
+ # Create the service account
116
+ gcloud iam service-accounts create uc-bq-reader \
117
+ --display-name="UltraCart BQ Reader" \
118
+ --project=YOUR_PROJECT_ID
119
+
120
+ # Download the JSON key
121
+ gcloud iam service-accounts keys create ./sa-key.json \
122
+ --iam-account=uc-bq-reader@YOUR_PROJECT_ID.iam.gserviceaccount.com
123
+ ```
124
+
125
+ **3. Register the service account in UltraCart:**
126
+
127
+ Go to the UltraCart dashboard and register the service account email (`uc-bq-reader@YOUR_PROJECT_ID.iam.gserviceaccount.com`) so UltraCart can provision BigQuery access for it. Your UltraCart admin assigns the taxonomy level.
128
+
129
+ **4. Set the environment variable:**
130
+
131
+ ```bash
132
+ export GOOGLE_APPLICATION_CREDENTIALS="/path/to/sa-key.json"
133
+ ```
134
+
135
+ Add this to your `.bashrc`, `.zshrc`, or CI environment variables for persistence.
136
+
137
+ **5. Verify it works:**
138
+
139
+ ```bash
140
+ uc-bq schema --list
141
+ ```
142
+
143
+ ### Troubleshooting Authentication
144
+
145
+ | Error | Fix |
146
+ |---|---|
147
+ | `Could not load the default credentials` | Run `gcloud auth application-default login` or set `GOOGLE_APPLICATION_CREDENTIALS` |
148
+ | `Permission denied` / `Access Denied` | Your Google account or service account hasn't been granted access in UltraCart. Contact your UltraCart admin. |
149
+ | `Project not found` | The project ID is derived from your merchant ID (`ultracart-dw-{merchantid}`). Check that your merchant IDs in `.ultracart-bq.json` are correct. |
150
+ | `Dataset not found` | Your taxonomy level may not include the dataset you're querying. Standard users can't access `ultracart_dw_medium`. |
151
+
152
+ ## Quick Start
153
+
154
+ ### 1. Install the Claude Code Skill
155
+
156
+ ```bash
157
+ uc-bq install-skill
158
+ ```
159
+
160
+ This copies the skill prompt to `~/.claude/skills/uc-bq/SKILL.md`. The skill teaches Claude Code how to work with UltraCart's BigQuery schema, write optimized SQL, create ECharts visualizations, and use the `uc-bq` CLI. You can preview the file with `uc-bq install-skill --dry-run` or read it directly at `skill/skill.md` in the package.
161
+
162
+ To remove the skill: `uc-bq install-skill --uninstall`
163
+
164
+ ### 2. Configure
165
+
166
+ ```bash
167
+ uc-bq init
168
+ ```
169
+
170
+ This prompts for your merchant ID(s), taxonomy level, and preferences, then writes `.ultracart-bq.json` and tests the connection. The BigQuery project ID is derived automatically from your merchant ID (`ultracart-dw-{merchantid}`).
171
+
172
+ Or create the config manually:
173
+
174
+ ```json
175
+ {
176
+ "default_merchant": "DEMO",
177
+ "merchants": {
178
+ "DEMO": { "taxonomy_level": "medium", "dataset": "ultracart_dw" }
179
+ },
180
+ "default_output_dir": "./reports",
181
+ "output_format": "png",
182
+ "chart_theme": "default",
183
+ "chart_defaults": { "width": 1200, "height": 600 },
184
+ "max_query_bytes": 10737418240,
185
+ "llm": {
186
+ "provider": "anthropic",
187
+ "api_key_env": "ANTHROPIC_API_KEY",
188
+ "analysis_model": "claude-sonnet-4-5-20250929",
189
+ "schema_filter_model": "claude-haiku-4-5-20251001"
190
+ }
191
+ }
192
+ ```
193
+
194
+ Add more merchants to manage multiple stores from one config:
195
+
196
+ ```json
197
+ {
198
+ "default_merchant": "DEMO",
199
+ "merchants": {
200
+ "DEMO": { "taxonomy_level": "medium", "dataset": "ultracart_dw" },
201
+ "DEMO2": { "taxonomy_level": "standard", "dataset": "ultracart_dw" }
202
+ }
203
+ }
204
+ ```
205
+
206
+ The `llm` section is optional. All fields within it are optional. If omitted, the CLI defaults to Anthropic. See [LLM Providers](#llm-providers) for details.
207
+
208
+ Use the global `--merchant` / `-m` flag to target a specific merchant on any command:
209
+
210
+ ```bash
211
+ uc-bq schema --list -m DEMO2
212
+ uc-bq run revenue-by-category -m DEMO2
213
+ ```
214
+
215
+ ### 3. Create a Report (with Claude Code)
216
+
217
+ In Claude Code, use the skill to ask a question:
218
+
219
+ ```
220
+ Show me revenue trends by product category for the last 90 days
221
+ ```
222
+
223
+ Claude Code will:
224
+ 1. Discover your schema via `uc-bq schema`
225
+ 2. Generate and test SQL via `uc-bq query`
226
+ 3. Create an ECharts visualization
227
+ 4. Render to PNG via `uc-bq render`
228
+ 5. Write an executive analysis
229
+ 6. Save a replayable report manifest
230
+
231
+ **Result:** A report directory under `./reports/{merchant_id}/{report-name}/` with `report.yaml`, `query.sql`, `chart.js`, `chart.png`, `report.pdf`, and `report.md`.
232
+
233
+ ### 4. Replay a Report (no Claude Code needed)
234
+
235
+ ```bash
236
+ # Replay with default date parameters
237
+ uc-bq run revenue-by-category
238
+
239
+ # Replay with custom date range
240
+ uc-bq run revenue-by-category --start_date=2026-01-01 --end_date=2026-03-28
241
+
242
+ # Replay all saved reports
243
+ uc-bq run-all --start_date=2026-01-01 --end_date=2026-03-28
244
+ ```
245
+
246
+ Replay executes the saved SQL, renders the saved chart config, generates a combined PDF (`report.pdf`) with the chart and executive analysis, and updates run history. Zero LLM calls.
247
+
248
+ ## CLI Reference
249
+
250
+ ### `uc-bq init`
251
+
252
+ Interactive setup. Creates `.ultracart-bq.json` and tests BigQuery connectivity.
253
+
254
+ ### `uc-bq config`
255
+
256
+ Manage merchants, external projects, and settings.
257
+
258
+ ```bash
259
+ uc-bq config show # Show current config
260
+ uc-bq config add-merchant <id> --taxonomy=X [--dataset=Y] # Add a merchant
261
+ uc-bq config remove-merchant <id> # Remove a merchant
262
+ uc-bq config add-project <alias> --project-id=X [--description=Y] # Register external project
263
+ uc-bq config remove-project <alias> # Remove external project
264
+ uc-bq config add-dataset <alias> <dataset> [--discover] # Add dataset to external project
265
+ uc-bq config remove-dataset <alias> <dataset> # Remove dataset
266
+ uc-bq config add-tables <alias> <dataset> <tables...> # Expose specific tables
267
+ uc-bq config remove-tables <alias> <dataset> <tables...> # Remove table access
268
+
269
+ # Delivery config
270
+ uc-bq config add-slack <report> <channel-id...> # Add Slack channel(s) to a report
271
+ uc-bq config remove-slack <report> <channel-id...> # Remove Slack channel(s)
272
+ uc-bq config set-email <report> --to=a@example.com,b@example.com --provider=sendgrid --subject="Weekly" # Set full email config
273
+ uc-bq config add-email <report> <email...> # Add email recipient(s)
274
+ uc-bq config remove-email <report> <email...> # Remove email recipient(s)
275
+ uc-bq config set-email-provider <report> <provider> # Set email provider
276
+ uc-bq config set-email-subject <report> <subject> # Set email subject line
277
+ uc-bq config show-delivery <report> # Show delivery config for a report
278
+
279
+ # Report parameter defaults
280
+ uc-bq config set-param <report> <param> <value> # Set a default parameter on a report
281
+ uc-bq config remove-param <report> <param> # Remove a default parameter
282
+ uc-bq config show-params <report> # Show parameter defaults for a report
283
+
284
+ # Deck parameter overrides
285
+ uc-bq config set-deck-param <deck> <param> <value> # Set a parameter override on a deck
286
+ uc-bq config remove-deck-param <deck> <param> # Remove a deck parameter override
287
+ uc-bq config show-deck-params <deck> # Show parameter overrides for a deck
288
+ ```
289
+
290
+ ### `uc-bq schema`
291
+
292
+ Explore your BigQuery schema, including external projects.
293
+
294
+ ```bash
295
+ # List all available tables
296
+ uc-bq schema --list
297
+
298
+ # Get schema for specific tables
299
+ uc-bq schema --tables=uc_orders,uc_items
300
+
301
+ # Filter schema columns by keyword
302
+ uc-bq schema --tables=uc_orders --filter="revenue,date,category"
303
+
304
+ # Output as JSON (for piping)
305
+ uc-bq schema --tables=uc_orders --format=json
306
+
307
+ # Browse an external GCP project before registering it
308
+ uc-bq schema --project=my-marketing-warehouse # list datasets
309
+ uc-bq schema --project=my-marketing-warehouse --dataset=X --list # list tables
310
+ uc-bq schema --project=my-marketing-warehouse --dataset=X --tables=Y # get schema
311
+
312
+ # Refresh cached external table schemas
313
+ uc-bq schema --refresh
314
+ ```
315
+
316
+ ### `uc-bq query`
317
+
318
+ Execute SQL against BigQuery.
319
+
320
+ ```bash
321
+ # Execute from a file with parameters
322
+ uc-bq query --file=query.sql --params='{"start_date":"2026-01-01","end_date":"2026-03-28"}'
323
+
324
+ # Execute inline SQL
325
+ uc-bq query --sql="SELECT COUNT(*) as cnt FROM \`ultracart-dw-mymerchant.ultracart_dw.uc_orders\`"
326
+
327
+ # Save results to JSON
328
+ uc-bq query --file=query.sql --params='...' --output=data.json
329
+
330
+ # Show more sample rows (default: 20)
331
+ uc-bq query --file=query.sql --params='...' --sample=50
332
+
333
+ # Bypass the cost safety check
334
+ uc-bq query --file=query.sql --params='...' --force
335
+
336
+ # Override the cost limit for this command (bytes)
337
+ uc-bq query --file=query.sql --params='...' --max-bytes=53687091200
338
+ ```
339
+
340
+ ### `uc-bq dry-run`
341
+
342
+ Estimate query cost before executing.
343
+
344
+ ```bash
345
+ uc-bq dry-run --file=query.sql --params='{"start_date":"2026-01-01","end_date":"2026-03-28"}'
346
+
347
+ # Output:
348
+ # Estimated bytes processed: 2.4 GB
349
+ # Estimated cost: $0.015
350
+ ```
351
+
352
+ ### `uc-bq validate`
353
+
354
+ Validate configuration or report manifests against JSON Schema.
355
+
356
+ ```bash
357
+ # Validate your config
358
+ uc-bq validate --config
359
+
360
+ # Validate a report manifest
361
+ uc-bq validate --manifest=./reports/revenue-by-category/report.yaml
362
+ ```
363
+
364
+ ### `uc-bq render`
365
+
366
+ Render an ECharts chart to PNG or PDF.
367
+
368
+ ```bash
369
+ # Render to PNG
370
+ uc-bq render --chart=chart.js --data=data.json --output=chart.png
371
+
372
+ # Render to PDF
373
+ uc-bq render --chart=chart.js --data=data.json --output=chart.pdf --format=pdf
374
+
375
+ # Render dashboard thumbnail (200x200)
376
+ uc-bq render --chart=chart.js --data=data.json --output=chart-thumb.png --dashboard
377
+
378
+ # Custom dimensions
379
+ uc-bq render --chart=chart.js --data=data.json --output=chart.png --width=1600 --height=900
380
+ ```
381
+
382
+ ### `uc-bq run`
383
+
384
+ Replay a saved report with fresh data.
385
+
386
+ ```bash
387
+ # Run with default parameters
388
+ uc-bq run revenue-by-category
389
+
390
+ # Override parameters
391
+ uc-bq run revenue-by-category --start_date=2026-01-01 --end_date=2026-03-28
392
+
393
+ # Skip analysis generation
394
+ uc-bq run revenue-by-category --no-analysis
395
+
396
+ # Generate PDF in landscape orientation (useful for wide charts)
397
+ uc-bq run revenue-by-category --landscape
398
+
399
+ # Run and deliver to Slack/email (as configured in the report manifest)
400
+ uc-bq run revenue-by-category --deliver
401
+
402
+ # Bypass the cost safety check
403
+ uc-bq run revenue-by-category --force
404
+
405
+ # Override the cost limit for this run (bytes)
406
+ uc-bq run revenue-by-category --max-bytes=53687091200
407
+ ```
408
+
409
+ ### `uc-bq run-all`
410
+
411
+ Replay all saved reports.
412
+
413
+ ```bash
414
+ # Run all with shared date range
415
+ uc-bq run-all --start_date=2026-01-01 --end_date=2026-03-28
416
+
417
+ # Run all without analysis
418
+ uc-bq run-all --no-analysis
419
+
420
+ # Run all in landscape orientation
421
+ uc-bq run-all --landscape
422
+
423
+ # Run all and deliver to Slack/email
424
+ uc-bq run-all --deliver --no-analysis
425
+
426
+ # Bypass the cost safety check for all reports
427
+ uc-bq run-all --force
428
+
429
+ # Override the cost limit for all reports (bytes)
430
+ uc-bq run-all --max-bytes=53687091200
431
+ ```
432
+
433
+ ### `uc-bq deck run <deck-name>`
434
+
435
+ Run all reports in a deck and generate a combined PDF.
436
+
437
+ ```bash
438
+ # Generate the deck PDF
439
+ uc-bq deck run weekly-executive
440
+
441
+ # Generate and deliver the deck
442
+ uc-bq deck run weekly-executive --deliver
443
+
444
+ # Skip analysis generation
445
+ uc-bq deck run weekly-executive --no-analysis
446
+
447
+ # Override parameters for all reports in the deck
448
+ uc-bq deck run weekly-executive --start_date=2026-01-01 --end_date=2026-03-31
449
+ ```
450
+
451
+ ### `uc-bq deck dashboard <deck-name>`
452
+
453
+ Generate a self-contained interactive HTML dashboard from a deck definition. Uses ECharts loaded from CDN with all chart data inlined — no server required. The output is a single HTML file with responsive layout, interactive tooltips, hover effects, and zoom.
454
+
455
+ ```bash
456
+ # Generate dashboard HTML
457
+ uc-bq deck dashboard weekly-executive
458
+
459
+ # Generate and open in browser
460
+ uc-bq deck dashboard weekly-executive --open
461
+ ```
462
+
463
+ Output: `reports/DEMO/decks/weekly-executive-dashboard.html`
464
+
465
+ The dashboard reuses the same deck definition and report data as `deck run`. Deploy the HTML file anywhere — S3, an internal web server, or open it directly from disk.
466
+
467
+ ### `uc-bq deck list`
468
+
469
+ List all defined decks.
470
+
471
+ ```bash
472
+ uc-bq deck list
473
+ ```
474
+
475
+ ### `uc-bq deck create <deck-name>`
476
+
477
+ Interactive deck creation.
478
+
479
+ ```bash
480
+ uc-bq deck create weekly-executive
481
+
482
+ # Create with inline options
483
+ uc-bq deck create weekly --title="Weekly" --reports=rev,ltv --params="start_date=start_of_year,end_date=today"
484
+ ```
485
+
486
+ ### `uc-bq list`
487
+
488
+ List all saved reports.
489
+
490
+ ```bash
491
+ uc-bq list
492
+
493
+ # Output:
494
+ # Name Last Run Status Parameters
495
+ # Revenue by Product Category 2026-03-28 OK 2 req, 2 opt
496
+ # Customer Cohort Analysis 2026-03-25 OK 3 req, 0 opt
497
+ ```
498
+
499
+ ### `uc-bq history`
500
+
501
+ Show run history for a report.
502
+
503
+ ```bash
504
+ uc-bq history revenue-by-category
505
+
506
+ # Output:
507
+ # Run Date Parameters Rows Bytes
508
+ # 2026-03-28 start=2025-12-28 end=2026-03-28 1,247 2.4 GB
509
+ # 2026-03-21 start=2025-12-21 end=2026-03-21 1,189 2.3 GB
510
+ ```
511
+
512
+ ## LLM Providers
513
+
514
+ The CLI supports 5 LLM providers for analysis generation (`uc-bq run` with API key) and schema filtering. All provider SDKs are bundled — just set your provider and API key.
515
+
516
+ **Note:** When using the skill interactively in Claude Code, the LLM provider config does not matter. Claude Code itself is the LLM doing the thinking. The provider config only applies to headless/scheduled operations (`--analysis-api-key`, `uc-bq run` with an API key, etc.).
517
+
518
+ ### Supported Providers
519
+
520
+ | Provider | SDK | API Key Env | Analysis Model | Filter Model |
521
+ |----------|-----|-------------|----------------|-------------|
522
+ | `anthropic` (default) | `@anthropic-ai/sdk` | `ANTHROPIC_API_KEY` | `claude-sonnet-4-5-20250929` | `claude-haiku-4-5-20251001` |
523
+ | `openai` | `openai` | `OPENAI_API_KEY` | `gpt-4o` | `gpt-4o-mini` |
524
+ | `grok` | `openai` | `XAI_API_KEY` | `grok-2` | `grok-2` |
525
+ | `bedrock` | `@aws-sdk/client-bedrock-runtime` | AWS credential chain | `anthropic.claude-sonnet-4-5-20250929-v1:0` | `anthropic.claude-haiku-4-5-20251001-v1:0` |
526
+ | `gemini` | `@google/generative-ai` | `GOOGLE_API_KEY` | `gemini-2.0-flash` | `gemini-2.0-flash-lite` |
527
+
528
+ ### Configuration
529
+
530
+ Add an `llm` section to `.ultracart-bq.json`:
531
+
532
+ ```json
533
+ {
534
+ "llm": {
535
+ "provider": "openai",
536
+ "api_key_env": "OPENAI_API_KEY",
537
+ "analysis_model": "gpt-4o",
538
+ "schema_filter_model": "gpt-4o-mini"
539
+ }
540
+ }
541
+ ```
542
+
543
+ All fields are optional. If omitted entirely, the CLI defaults to Anthropic.
544
+
545
+ ### `--llm-provider` flag
546
+
547
+ Override the configured provider for a single command:
548
+
549
+ ```bash
550
+ uc-bq run revenue-by-category --llm-provider=openai --analysis-api-key=$OPENAI_API_KEY
551
+ uc-bq run-all --llm-provider=gemini --deliver
552
+ ```
553
+
554
+ This is a global flag available on all commands. It overrides the `llm.provider` value from your config for that invocation only.
555
+
556
+ ### Provider Installation
557
+
558
+ All provider SDKs are bundled with the package. Just install `@ultracart/bq-skill` and all providers are available:
559
+
560
+ ```bash
561
+ npm install -g @ultracart/bq-skill
562
+ ```
563
+
564
+ ## Report Structure
565
+
566
+ Each report is a self-contained directory, scoped by merchant. Decks live in a `decks/` directory alongside reports:
567
+
568
+ ```
569
+ ./reports/DEMO/
570
+ ├── revenue-by-category/
571
+ │ ├── report.yaml # Manifest — parameters, config, metadata
572
+ │ ├── query.sql # Parameterized SQL template
573
+ │ ├── chart.js # Battle-hardened ECharts formatChartData() function
574
+ │ ├── chart.png # Full visualization
575
+ │ ├── chart-dashboard.png # 200x200 dashboard thumbnail
576
+ │ ├── report.pdf # Combined PDF with chart + executive analysis
577
+ │ ├── analysis_prompt.md # System prompt for analysis generation
578
+ │ ├── report.md # Executive analysis
579
+ │ └── data.json # Query results (optional)
580
+ ├── top-products-by-revenue/
581
+ │ └── ...
582
+ └── decks/
583
+ ├── weekly-executive.yaml # Deck definition (committed to git)
584
+ ├── weekly-executive.pdf # Generated deck PDF (not committed)
585
+ └── weekly-executive-dashboard.html # Generated interactive dashboard (not committed)
586
+ ```
587
+
588
+ The `report.yaml` manifest captures everything needed to replay:
589
+
590
+ ```yaml
591
+ name: "Revenue by Product Category"
592
+ description: "Daily revenue trends broken down by product category"
593
+ created: 2026-03-28
594
+ last_run: 2026-03-28
595
+ prompt: "Show me revenue trends by product category for the last 90 days"
596
+
597
+ parameters:
598
+ - name: start_date
599
+ type: date
600
+ label: "Start Date"
601
+ required: true
602
+ default: "-90d"
603
+ - name: end_date
604
+ type: date
605
+ label: "End Date"
606
+ required: true
607
+ default: "today"
608
+
609
+ delivery: # Optional: auto-deliver on --deliver
610
+ slack:
611
+ channels: ["C0123456789", "C9876543210"]
612
+ email:
613
+ to: ["ceo@example.com", "marketing@example.com"]
614
+ subject: "Weekly: Revenue by Product Category"
615
+ provider: "sendgrid"
616
+
617
+ config:
618
+ merchant_id: "DEMO"
619
+ project_id: "ultracart-dw-DEMO"
620
+ taxonomy_level: "medium"
621
+ dataset: "ultracart_dw"
622
+ tables_used: ["uc_orders"]
623
+
624
+ sql_file: "query.sql"
625
+ chart:
626
+ type: "stacked-area"
627
+ echarts_file: "chart.js"
628
+ output_format: "png"
629
+ width: 1200
630
+ height: 600
631
+
632
+ analysis:
633
+ landscape: true # Optional: generate PDF in landscape orientation
634
+ ```
635
+
636
+ ## Report Delivery
637
+
638
+ Reports can be automatically delivered to Slack channels and email recipients after generation. Add a `delivery` section to any report's `report.yaml`:
639
+
640
+ ```yaml
641
+ delivery:
642
+ slack:
643
+ channels: ["C0123456789", "C9876543210"]
644
+ email:
645
+ to: ["ceo@example.com", "marketing@example.com"]
646
+ subject: "Weekly: Revenue by Payment Method"
647
+ provider: "sendgrid"
648
+ ```
649
+
650
+ Then use `--deliver` on `run` or `run-all`:
651
+
652
+ ```bash
653
+ uc-bq run revenue-by-category --deliver
654
+ uc-bq run-all --deliver --no-analysis
655
+ ```
656
+
657
+ Supported email providers: SendGrid, Postmark, Mailgun, Resend, AWS SES. All via REST APIs, no SMTP, no extra npm dependencies (except optional `@aws-sdk/client-sesv2` for SES). Slack delivery uses the Slack API with a bot token.
658
+
659
+ Delivery failures are logged but never crash the run. If Slack is down or an email bounces, the report still generates successfully.
660
+
661
+ See [docs/REPORT-DELIVERY.md](docs/REPORT-DELIVERY.md) for full setup instructions, provider configuration, environment variables, and multi-client delivery patterns.
662
+
663
+ ## Report Alarms
664
+
665
+ Alarms let you define conditions on your report data that trigger notifications when something needs attention -- management by exception. Alarms evaluate automatically as part of the normal `uc-bq run` pipeline.
666
+
667
+ ### Alarm types
668
+
669
+ - **Threshold** -- alert when a metric crosses a static value (e.g., revenue < $10K)
670
+ - **Percent change** -- alert when a metric changes by more than X% vs the previous run
671
+ - **Missing data** -- alert when a query returns zero rows
672
+
673
+ ### Quick example
674
+
675
+ ```yaml
676
+ # In report.yaml
677
+ alarms:
678
+ - name: "Revenue Drop"
679
+ type: pct_change
680
+ metric: "total_revenue"
681
+ aggregate: "sum"
682
+ operator: "<"
683
+ value: -20
684
+ compare_to: "previous_run"
685
+ severity: high
686
+ cooldown: "24h"
687
+
688
+ delivery:
689
+ mode: "alarm_only" # Only deliver when alarms fire
690
+ slack:
691
+ channels: ["C0123456789"]
692
+ mention_on_alarm: "@channel" # Ping for critical alarms
693
+ ```
694
+
695
+ ### Alarm CLI commands
696
+
697
+ ```bash
698
+ uc-bq config add-alarm <report> --name "..." --type threshold --metric "..." \
699
+ --aggregate sum --operator "<" --value 10000 --severity high --cooldown 24h
700
+ uc-bq config show-alarms <report>
701
+ uc-bq config remove-alarm <report> "Alarm Name"
702
+ uc-bq config set-delivery-mode <report> alarm_only
703
+ uc-bq alarm test <report> # Test against current data.json
704
+ uc-bq alarm history <report> # View alarm_state.json history
705
+ ```
706
+
707
+ Alarm state is tracked in `alarm_state.json` per report (separate from `report.yaml` for clean diffs). Severity controls notification behavior: `low` is inline, `high` gets a distinct notification, `critical` adds Slack mentions. Cooldown prevents repeated notifications for persistent conditions.
708
+
709
+ See [docs/ALARMS.md](docs/ALARMS.md) for full alarm documentation including severity levels, cooldown, delivery modes, deck alarm aggregation, GitHub Actions integration, and recipes.
710
+
711
+ ## Report Decks
712
+
713
+ Decks combine multiple reports into a single PDF with a branded cover page, clickable table of contents, and all charts + analyses in one document. Instead of sending N separate files, deliver one polished deck.
714
+
715
+ ### Deck definition
716
+
717
+ Create a deck YAML file in `reports/{merchant_id}/decks/`:
718
+
719
+ ```yaml
720
+ # reports/DEMO/decks/weekly-executive.yaml
721
+ name: "Weekly Executive Briefing"
722
+ title: "DEMO Weekly Report Deck"
723
+ cover:
724
+ company: "DEMO Commerce Inc."
725
+ logo_url: "https://example.com/logo.png"
726
+ parameters: # Optional: override defaults for all reports
727
+ start_date: "start_of_year"
728
+ end_date: "today"
729
+ reports:
730
+ - revenue-by-payment-method
731
+ - ltv-by-monthly-cohort
732
+ - top-products-by-revenue
733
+ landscape: true
734
+ delivery:
735
+ slack:
736
+ channels: ["C0123456789"]
737
+ email:
738
+ to: ["ceo@example.com", "cfo@example.com"]
739
+ subject: "Weekly Executive Briefing"
740
+ provider: "sendgrid"
741
+ ```
742
+
743
+ Deck parameters flow down to all reports as overrides. Priority: CLI flags > deck parameters > report defaults.
744
+
745
+ ### Deck CLI commands
746
+
747
+ ```bash
748
+ uc-bq deck run weekly-executive # Run all reports and generate combined PDF
749
+ uc-bq deck run weekly-executive --deliver # Run and deliver the deck PDF
750
+ uc-bq deck dashboard weekly-executive # Generate interactive HTML dashboard
751
+ uc-bq deck dashboard weekly-executive --open # Generate and open in browser
752
+ uc-bq deck list # List defined decks
753
+ uc-bq deck create weekly-executive # Interactive deck creation
754
+ ```
755
+
756
+ Decks don't replace individual report delivery -- they're an additional option. Each report is still independently runnable via `uc-bq run`. When `--deliver` is used on a deck, ONE combined PDF is sent instead of N individual files.
757
+
758
+ Decks also support an interactive HTML dashboard mode via `uc-bq deck dashboard`. This generates a single self-contained HTML file with live ECharts visualizations — tooltips, hover effects, zoom, and responsive layout — that can be opened from disk or deployed to any web server.
759
+
760
+ See [docs/DECKS.md](docs/DECKS.md) for full deck documentation including cover page customization, multi-client patterns, and GitHub Actions integration.
761
+
762
+ ## Scheduling Reports
763
+
764
+ Since `uc-bq run` is pure Node.js with no LLM dependency, you can schedule it with cron or CI/CD. If you want AI-generated analysis on scheduled runs, set the appropriate API key for your configured LLM provider:
765
+
766
+ ```bash
767
+ # Crontab: refresh all reports every Monday at 6am (no analysis)
768
+ 0 6 * * 1 cd /path/to/project && uc-bq run-all --no-analysis --start_date=-7d --end_date=today
769
+
770
+ # With analysis using your configured provider (set the matching API key)
771
+ 0 6 * * 1 cd /path/to/project && ANTHROPIC_API_KEY=sk-... uc-bq run-all
772
+ 0 6 * * 1 cd /path/to/project && OPENAI_API_KEY=sk-... uc-bq run-all --llm-provider=openai
773
+ ```
774
+
775
+ ```yaml
776
+ # GitHub Actions
777
+ name: Weekly Reports
778
+ on:
779
+ schedule:
780
+ - cron: '0 6 * * 1'
781
+ jobs:
782
+ reports:
783
+ runs-on: ubuntu-latest
784
+ steps:
785
+ - uses: actions/checkout@v4
786
+ - uses: actions/setup-node@v4
787
+ with: { node-version: '24' }
788
+ - run: npm install -g @ultracart/bq-skill
789
+ - uses: google-github-actions/auth@v2
790
+ with: { credentials_json: '${{ secrets.GCP_SA_KEY }}' }
791
+ - run: uc-bq run-all --deliver --no-analysis
792
+ env:
793
+ SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
794
+ EMAIL_FROM: ${{ vars.EMAIL_FROM }}
795
+ SENDGRID_API_KEY: ${{ secrets.SENDGRID_API_KEY }}
796
+ # Set the API key matching your configured LLM provider (if using analysis):
797
+ # ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
798
+ # OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
799
+ # XAI_API_KEY: ${{ secrets.XAI_API_KEY }}
800
+ # GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
801
+ - uses: actions/upload-artifact@v4
802
+ with: { name: reports, path: './reports/**/chart.png' }
803
+ ```
804
+
805
+ ## Cost Protection
806
+
807
+ Every query execution (`query`, `run`, `run-all`) automatically runs a BigQuery dry-run first to check the estimated bytes processed. If the estimate exceeds the safety limit, the query is aborted before it runs.
808
+
809
+ **Default limit: 10 GB** (~$0.06 at BigQuery on-demand pricing of $6.25/TB).
810
+
811
+ Example error:
812
+
813
+ ```
814
+ Error: Query would process 45.2 GB (estimated cost: $0.2825), which exceeds the
815
+ safety limit of 10.0 GB. Use --force to execute anyway, or set a higher limit
816
+ with --max-bytes.
817
+ ```
818
+
819
+ ### Overriding the limit
820
+
821
+ | Method | Scope | Example |
822
+ |---|---|---|
823
+ | `--force` flag | Single command | `uc-bq query --file=q.sql --force` |
824
+ | `--max-bytes` flag | Single command | `uc-bq query --file=q.sql --max-bytes=53687091200` (50 GB) |
825
+ | `max_query_bytes` in config | All commands | Set in `.ultracart-bq.json` (bytes). Set to `0` to disable the check entirely. |
826
+
827
+ The `--force` and `--max-bytes` flags are available on `query`, `run`, and `run-all`.
828
+
829
+ ## Taxonomy Levels
830
+
831
+ UltraCart controls data access via taxonomy levels assigned by your account administrator:
832
+
833
+ | Level | Access |
834
+ |---|---|
835
+ | `standard` | No PII — order totals, item data, analytics |
836
+ | `low` | Minimal PII |
837
+ | `medium` | Includes email, addresses, customer details |
838
+ | `high` | Full access to all fields |
839
+
840
+ Your taxonomy level determines which BigQuery datasets and columns are available. The CLI and skill automatically respect these boundaries.
841
+
842
+ ## Available Datasets
843
+
844
+ | Dataset | Description | Access |
845
+ |---|---|---|
846
+ | `ultracart_dw` | Standard tables — no PII | All users |
847
+ | `ultracart_dw_medium` | Includes PII fields | Medium/High taxonomy |
848
+ | `ultracart_dw_streaming` | Analytics sessions, screen recordings | All users |
849
+ | `ultracart_dw_linked` | Parent/child aggregated data | Parent accounts only |
850
+
851
+ ## External Projects
852
+
853
+ Merchants can register external GCP projects (e.g., marketing data from Funnel.io, DBT warehouses) alongside their UltraCart data. You explicitly choose which datasets and tables to expose.
854
+
855
+ ### Browsing before registering
856
+
857
+ Use `uc-bq schema --project` to explore an external project before adding it to your config:
858
+
859
+ ```bash
860
+ uc-bq schema --project=my-marketing-warehouse # list datasets
861
+ uc-bq schema --project=my-marketing-warehouse --dataset=google_ads_data --list # list tables
862
+ uc-bq schema --project=my-marketing-warehouse --dataset=google_ads_data --tables=funnel_data # get schema
863
+ ```
864
+
865
+ ### Registering an external project
866
+
867
+ Use the `config` commands to add the project, datasets, and tables:
868
+
869
+ ```bash
870
+ uc-bq config add-project marketing --project-id=my-marketing-warehouse --description="Marketing data from Funnel.io"
871
+ uc-bq config add-dataset marketing google_ads_data
872
+ uc-bq config add-tables marketing google_ads_data funnel_data
873
+ ```
874
+
875
+ Or add it directly in `.ultracart-bq.json`:
876
+
877
+ ```json
878
+ {
879
+ "default_merchant": "DEMO",
880
+ "merchants": {
881
+ "DEMO": {
882
+ "taxonomy_level": "medium",
883
+ "dataset": "ultracart_dw",
884
+ "external_projects": {
885
+ "marketing": {
886
+ "project_id": "my-marketing-warehouse",
887
+ "description": "Marketing data from Funnel.io",
888
+ "datasets": {
889
+ "google_ads_data": ["funnel_data"]
890
+ }
891
+ }
892
+ }
893
+ }
894
+ }
895
+ }
896
+ ```
897
+
898
+ Once registered, external tables appear alongside UltraCart tables in `uc-bq schema --list` and are available for queries and reports.
899
+
900
+ ### Schema caching
901
+
902
+ External table schemas are cached on-demand at `.ultracart-bq-cache/` to avoid repeated BigQuery metadata lookups. To refresh the cache:
903
+
904
+ ```bash
905
+ uc-bq schema --refresh
906
+ ```
907
+
908
+ ## Relative Date Expressions
909
+
910
+ Report parameters support relative date expressions that resolve at replay time:
911
+
912
+ | Expression | Meaning |
913
+ |---|---|
914
+ | `today` | Current date |
915
+ | `yesterday` | Previous day |
916
+ | `-Nd` | N days ago (e.g., `-90d`) |
917
+ | `-Nw` | N weeks ago |
918
+ | `-Nm` | N months ago |
919
+ | `-Ny` | N years ago |
920
+ | `start_of_week` | Monday of the current week |
921
+ | `start_of_last_month` | First day of previous month |
922
+ | `start_of_last_quarter` | First day of previous quarter |
923
+ | `start_of_last_year` | January 1 of previous year |
924
+ | `end_of_last_month` | Last day of previous month |
925
+ | `end_of_last_quarter` | Last day of previous quarter |
926
+ | `end_of_last_year` | December 31 of previous year |
927
+
928
+ ## Development
929
+
930
+ ```bash
931
+ git clone https://github.com/UltraCart/uc-bq-claude-skill.git
932
+ cd uc-bq-claude-skill
933
+ npm install
934
+ npm run build # Compile TypeScript
935
+ npm run dev # Watch mode
936
+ node dist/cli.js # Run locally
937
+ ```
938
+
939
+ ## Documentation
940
+
941
+ - [CLI Reference](docs/CLI-REFERENCE.md) — Full command reference with examples
942
+ - [Report Delivery](docs/REPORT-DELIVERY.md) — Slack, email, and provider setup
943
+ - [Report Decks](docs/DECKS.md) — Combined PDFs, dashboards, and cover pages
944
+ - [Alarms](docs/ALARMS.md) — Threshold, percent change, and missing data alerts
945
+ - [Multi-Client](docs/MULTI-CLIENT.md) — Managing multiple merchant accounts
946
+ - [GitHub Actions](docs/GITHUB-ACTIONS.md) — CI/CD scheduling and automation
947
+
948
+ ## License
949
+
950
+ Apache 2.0 — see [LICENSE](LICENSE) for full terms.
951
+
952
+ This software is provided "AS IS", without warranties of any kind. See the license for the complete disclaimer of warranty and limitation of liability.