@cloudgrid-io/mcp 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (390) hide show
  1. package/package.json +1 -1
  2. package/src/corpus/capability-map.md +82 -2
  3. package/src/corpus/examples/crm/index.md +273 -0
  4. package/src/corpus/examples/kanban/index.md +256 -0
  5. package/src/corpus/templates/_cloudgrid.yaml.reference +228 -0
  6. package/src/corpus/templates/admin-dashboard/README.md +75 -0
  7. package/src/corpus/templates/admin-dashboard/cloudgrid.yaml +233 -0
  8. package/src/corpus/templates/admin-dashboard/index.md +81 -0
  9. package/src/corpus/templates/admin-dashboard/services/web/app/api/orders/route.js +64 -0
  10. package/src/corpus/templates/admin-dashboard/services/web/app/api/users/route.js +63 -0
  11. package/src/corpus/templates/admin-dashboard/services/web/app/layout.js +39 -0
  12. package/src/corpus/templates/admin-dashboard/services/web/app/page.js +73 -0
  13. package/src/corpus/templates/admin-dashboard/services/web/app/resource-table.js +94 -0
  14. package/src/corpus/templates/admin-dashboard/services/web/lib/db.js +32 -0
  15. package/src/corpus/templates/admin-dashboard/services/web/package.json +16 -0
  16. package/src/corpus/templates/ai-app/cloudgrid.yaml +225 -11
  17. package/src/corpus/templates/ai-app/index.md +3 -11
  18. package/src/corpus/templates/ai-knowledge-base/AGENTS.md +254 -0
  19. package/src/corpus/templates/ai-knowledge-base/README.md +28 -0
  20. package/src/corpus/templates/ai-knowledge-base/cloudgrid.yaml +238 -0
  21. package/src/corpus/templates/ai-knowledge-base/index.md +81 -0
  22. package/src/corpus/templates/analytics-dashboard/README.md +85 -0
  23. package/src/corpus/templates/analytics-dashboard/cloudgrid.yaml +232 -0
  24. package/src/corpus/templates/analytics-dashboard/index.md +316 -0
  25. package/src/corpus/templates/analytics-dashboard/services/web/app/api/events/route.js +60 -0
  26. package/src/corpus/templates/analytics-dashboard/services/web/app/event-form.js +100 -0
  27. package/src/corpus/templates/analytics-dashboard/services/web/app/layout.js +41 -0
  28. package/src/corpus/templates/analytics-dashboard/services/web/app/page.js +54 -0
  29. package/src/corpus/templates/analytics-dashboard/services/web/lib/db.js +32 -0
  30. package/src/corpus/templates/analytics-dashboard/services/web/package.json +16 -0
  31. package/src/corpus/templates/api-dashboard/README.md +84 -0
  32. package/src/corpus/templates/api-dashboard/cloudgrid.yaml +233 -0
  33. package/src/corpus/templates/api-dashboard/index.md +310 -0
  34. package/src/corpus/templates/api-dashboard/services/web/app/api/requests/route.js +62 -0
  35. package/src/corpus/templates/api-dashboard/services/web/app/dashboard.js +156 -0
  36. package/src/corpus/templates/api-dashboard/services/web/app/layout.js +42 -0
  37. package/src/corpus/templates/api-dashboard/services/web/app/page.js +39 -0
  38. package/src/corpus/templates/api-dashboard/services/web/lib/db.js +32 -0
  39. package/src/corpus/templates/api-dashboard/services/web/package.json +16 -0
  40. package/src/corpus/templates/api-docs/README.md +28 -0
  41. package/src/corpus/templates/api-docs/cloudgrid.yaml +228 -0
  42. package/src/corpus/templates/api-docs/index.html +136 -0
  43. package/src/corpus/templates/api-docs/index.md +28 -0
  44. package/src/corpus/templates/api-service/cloudgrid.yaml +224 -9
  45. package/src/corpus/templates/api-service/index.md +3 -11
  46. package/src/corpus/templates/app-with-data/cloudgrid.yaml +226 -8
  47. package/src/corpus/templates/app-with-data/index.md +3 -8
  48. package/src/corpus/templates/appointment-booking/AGENTS.md +223 -0
  49. package/src/corpus/templates/appointment-booking/README.md +16 -0
  50. package/src/corpus/templates/appointment-booking/cloudgrid.yaml +250 -0
  51. package/src/corpus/templates/appointment-booking/index.md +72 -0
  52. package/src/corpus/templates/approval-workflow/AGENTS.md +170 -0
  53. package/src/corpus/templates/approval-workflow/README.md +12 -0
  54. package/src/corpus/templates/approval-workflow/cloudgrid.yaml +237 -0
  55. package/src/corpus/templates/approval-workflow/index.md +58 -0
  56. package/src/corpus/templates/billing-dashboard/AGENTS.md +199 -0
  57. package/src/corpus/templates/billing-dashboard/README.md +18 -0
  58. package/src/corpus/templates/billing-dashboard/cloudgrid.yaml +235 -0
  59. package/src/corpus/templates/billing-dashboard/index.md +87 -0
  60. package/src/corpus/templates/blog-cms/README.md +94 -0
  61. package/src/corpus/templates/blog-cms/cloudgrid.yaml +233 -0
  62. package/src/corpus/templates/blog-cms/index.md +358 -0
  63. package/src/corpus/templates/blog-cms/services/web/app/admin/admin-editor.js +133 -0
  64. package/src/corpus/templates/blog-cms/services/web/app/admin/page.js +33 -0
  65. package/src/corpus/templates/blog-cms/services/web/app/api/posts/route.js +84 -0
  66. package/src/corpus/templates/blog-cms/services/web/app/layout.js +47 -0
  67. package/src/corpus/templates/blog-cms/services/web/app/page.js +56 -0
  68. package/src/corpus/templates/blog-cms/services/web/app/posts/[slug]/page.js +45 -0
  69. package/src/corpus/templates/blog-cms/services/web/lib/db.js +32 -0
  70. package/src/corpus/templates/blog-cms/services/web/package.json +16 -0
  71. package/src/corpus/templates/booking-system/AGENTS.md +189 -0
  72. package/src/corpus/templates/booking-system/README.md +17 -0
  73. package/src/corpus/templates/booking-system/cloudgrid.yaml +248 -0
  74. package/src/corpus/templates/booking-system/index.md +86 -0
  75. package/src/corpus/templates/calendar-scheduler/AGENTS.md +226 -0
  76. package/src/corpus/templates/calendar-scheduler/README.md +25 -0
  77. package/src/corpus/templates/calendar-scheduler/cloudgrid.yaml +259 -0
  78. package/src/corpus/templates/calendar-scheduler/index.md +85 -0
  79. package/src/corpus/templates/changelog/README.md +27 -0
  80. package/src/corpus/templates/changelog/cloudgrid.yaml +228 -0
  81. package/src/corpus/templates/changelog/index.html +80 -0
  82. package/src/corpus/templates/changelog/index.md +28 -0
  83. package/src/corpus/templates/company-website/README.md +54 -0
  84. package/src/corpus/templates/company-website/cloudgrid.yaml +233 -0
  85. package/src/corpus/templates/company-website/index.html +309 -0
  86. package/src/corpus/templates/company-website/index.md +29 -0
  87. package/src/corpus/templates/course-platform/AGENTS.md +161 -0
  88. package/src/corpus/templates/course-platform/README.md +26 -0
  89. package/src/corpus/templates/course-platform/cloudgrid.yaml +237 -0
  90. package/src/corpus/templates/course-platform/index.md +70 -0
  91. package/src/corpus/templates/crm/README.md +72 -0
  92. package/src/corpus/templates/crm/cloudgrid.yaml +233 -0
  93. package/src/corpus/templates/crm/index.md +71 -0
  94. package/src/corpus/templates/crm/services/web/app/api/contacts/route.js +80 -0
  95. package/src/corpus/templates/crm/services/web/app/contact-manager.js +102 -0
  96. package/src/corpus/templates/crm/services/web/app/layout.js +35 -0
  97. package/src/corpus/templates/crm/services/web/app/page.js +34 -0
  98. package/src/corpus/templates/crm/services/web/lib/db.js +32 -0
  99. package/src/corpus/templates/crm/services/web/package.json +16 -0
  100. package/src/corpus/templates/dashboard/cloudgrid.yaml +228 -4
  101. package/src/corpus/templates/dashboard/index.md +3 -5
  102. package/src/corpus/templates/deck/cloudgrid.yaml +228 -4
  103. package/src/corpus/templates/deck/index.md +3 -5
  104. package/src/corpus/templates/directory/README.md +75 -0
  105. package/src/corpus/templates/directory/cloudgrid.yaml +233 -0
  106. package/src/corpus/templates/directory/index.md +334 -0
  107. package/src/corpus/templates/directory/services/web/app/api/entries/route.js +63 -0
  108. package/src/corpus/templates/directory/services/web/app/directory-list.js +146 -0
  109. package/src/corpus/templates/directory/services/web/app/layout.js +44 -0
  110. package/src/corpus/templates/directory/services/web/app/page.js +38 -0
  111. package/src/corpus/templates/directory/services/web/lib/db.js +32 -0
  112. package/src/corpus/templates/directory/services/web/package.json +16 -0
  113. package/src/corpus/templates/docs-site/README.md +28 -0
  114. package/src/corpus/templates/docs-site/cloudgrid.yaml +228 -0
  115. package/src/corpus/templates/docs-site/index.html +122 -0
  116. package/src/corpus/templates/docs-site/index.md +28 -0
  117. package/src/corpus/templates/erp/AGENTS.md +116 -0
  118. package/src/corpus/templates/erp/README.md +17 -0
  119. package/src/corpus/templates/erp/cloudgrid.yaml +235 -0
  120. package/src/corpus/templates/erp/index.md +81 -0
  121. package/src/corpus/templates/event-board/README.md +74 -0
  122. package/src/corpus/templates/event-board/cloudgrid.yaml +233 -0
  123. package/src/corpus/templates/event-board/index.md +299 -0
  124. package/src/corpus/templates/event-board/services/web/app/api/events/route.js +61 -0
  125. package/src/corpus/templates/event-board/services/web/app/event-form.js +118 -0
  126. package/src/corpus/templates/event-board/services/web/app/layout.js +39 -0
  127. package/src/corpus/templates/event-board/services/web/app/page.js +34 -0
  128. package/src/corpus/templates/event-board/services/web/lib/db.js +32 -0
  129. package/src/corpus/templates/event-board/services/web/package.json +16 -0
  130. package/src/corpus/templates/expense-tracker/README.md +76 -0
  131. package/src/corpus/templates/expense-tracker/cloudgrid.yaml +233 -0
  132. package/src/corpus/templates/expense-tracker/index.md +305 -0
  133. package/src/corpus/templates/expense-tracker/services/web/app/api/expenses/route.js +61 -0
  134. package/src/corpus/templates/expense-tracker/services/web/app/expense-form.js +145 -0
  135. package/src/corpus/templates/expense-tracker/services/web/app/layout.js +42 -0
  136. package/src/corpus/templates/expense-tracker/services/web/app/page.js +34 -0
  137. package/src/corpus/templates/expense-tracker/services/web/lib/db.js +32 -0
  138. package/src/corpus/templates/expense-tracker/services/web/package.json +16 -0
  139. package/src/corpus/templates/feature-request-board/README.md +87 -0
  140. package/src/corpus/templates/feature-request-board/cloudgrid.yaml +233 -0
  141. package/src/corpus/templates/feature-request-board/index.md +317 -0
  142. package/src/corpus/templates/feature-request-board/services/web/app/api/requests/route.js +92 -0
  143. package/src/corpus/templates/feature-request-board/services/web/app/board.js +91 -0
  144. package/src/corpus/templates/feature-request-board/services/web/app/layout.js +43 -0
  145. package/src/corpus/templates/feature-request-board/services/web/app/page.js +35 -0
  146. package/src/corpus/templates/feature-request-board/services/web/lib/db.js +32 -0
  147. package/src/corpus/templates/feature-request-board/services/web/package.json +16 -0
  148. package/src/corpus/templates/financial-dashboard/README.md +80 -0
  149. package/src/corpus/templates/financial-dashboard/cloudgrid.yaml +233 -0
  150. package/src/corpus/templates/financial-dashboard/index.md +326 -0
  151. package/src/corpus/templates/financial-dashboard/services/web/app/api/entries/route.js +63 -0
  152. package/src/corpus/templates/financial-dashboard/services/web/app/entry-board.js +130 -0
  153. package/src/corpus/templates/financial-dashboard/services/web/app/layout.js +46 -0
  154. package/src/corpus/templates/financial-dashboard/services/web/app/page.js +31 -0
  155. package/src/corpus/templates/financial-dashboard/services/web/lib/db.js +32 -0
  156. package/src/corpus/templates/financial-dashboard/services/web/package.json +16 -0
  157. package/src/corpus/templates/forum/AGENTS.md +196 -0
  158. package/src/corpus/templates/forum/README.md +12 -0
  159. package/src/corpus/templates/forum/cloudgrid.yaml +237 -0
  160. package/src/corpus/templates/forum/index.md +66 -0
  161. package/src/corpus/templates/hr-portal/AGENTS.md +174 -0
  162. package/src/corpus/templates/hr-portal/README.md +14 -0
  163. package/src/corpus/templates/hr-portal/cloudgrid.yaml +237 -0
  164. package/src/corpus/templates/hr-portal/index.md +56 -0
  165. package/src/corpus/templates/internal-tools-portal/AGENTS.md +201 -0
  166. package/src/corpus/templates/internal-tools-portal/README.md +17 -0
  167. package/src/corpus/templates/internal-tools-portal/cloudgrid.yaml +237 -0
  168. package/src/corpus/templates/internal-tools-portal/index.md +62 -0
  169. package/src/corpus/templates/inventory/README.md +71 -0
  170. package/src/corpus/templates/inventory/cloudgrid.yaml +233 -0
  171. package/src/corpus/templates/inventory/index.md +68 -0
  172. package/src/corpus/templates/inventory/services/web/app/api/items/route.js +88 -0
  173. package/src/corpus/templates/inventory/services/web/app/inventory-manager.js +101 -0
  174. package/src/corpus/templates/inventory/services/web/app/layout.js +36 -0
  175. package/src/corpus/templates/inventory/services/web/app/page.js +37 -0
  176. package/src/corpus/templates/inventory/services/web/lib/db.js +32 -0
  177. package/src/corpus/templates/inventory/services/web/package.json +16 -0
  178. package/src/corpus/templates/invoice/README.md +71 -0
  179. package/src/corpus/templates/invoice/cloudgrid.yaml +233 -0
  180. package/src/corpus/templates/invoice/index.md +68 -0
  181. package/src/corpus/templates/invoice/services/web/app/api/invoices/route.js +82 -0
  182. package/src/corpus/templates/invoice/services/web/app/invoice-manager.js +101 -0
  183. package/src/corpus/templates/invoice/services/web/app/layout.js +35 -0
  184. package/src/corpus/templates/invoice/services/web/app/page.js +34 -0
  185. package/src/corpus/templates/invoice/services/web/lib/db.js +32 -0
  186. package/src/corpus/templates/invoice/services/web/package.json +16 -0
  187. package/src/corpus/templates/job-board/README.md +71 -0
  188. package/src/corpus/templates/job-board/cloudgrid.yaml +233 -0
  189. package/src/corpus/templates/job-board/index.md +68 -0
  190. package/src/corpus/templates/job-board/services/web/app/api/jobs/route.js +66 -0
  191. package/src/corpus/templates/job-board/services/web/app/job-board.js +73 -0
  192. package/src/corpus/templates/job-board/services/web/app/layout.js +35 -0
  193. package/src/corpus/templates/job-board/services/web/app/page.js +32 -0
  194. package/src/corpus/templates/job-board/services/web/lib/db.js +32 -0
  195. package/src/corpus/templates/job-board/services/web/package.json +16 -0
  196. package/src/corpus/templates/kanban/README.md +72 -0
  197. package/src/corpus/templates/kanban/cloudgrid.yaml +233 -0
  198. package/src/corpus/templates/kanban/index.md +71 -0
  199. package/src/corpus/templates/kanban/services/web/app/api/cards/route.js +70 -0
  200. package/src/corpus/templates/kanban/services/web/app/board.js +93 -0
  201. package/src/corpus/templates/kanban/services/web/app/layout.js +37 -0
  202. package/src/corpus/templates/kanban/services/web/app/page.js +32 -0
  203. package/src/corpus/templates/kanban/services/web/lib/db.js +32 -0
  204. package/src/corpus/templates/kanban/services/web/package.json +16 -0
  205. package/src/corpus/templates/landing-page/cloudgrid.yaml +228 -4
  206. package/src/corpus/templates/landing-page/index.md +3 -5
  207. package/src/corpus/templates/lms/AGENTS.md +193 -0
  208. package/src/corpus/templates/lms/README.md +27 -0
  209. package/src/corpus/templates/lms/cloudgrid.yaml +237 -0
  210. package/src/corpus/templates/lms/index.md +79 -0
  211. package/src/corpus/templates/marketplace/AGENTS.md +208 -0
  212. package/src/corpus/templates/marketplace/README.md +22 -0
  213. package/src/corpus/templates/marketplace/cloudgrid.yaml +233 -0
  214. package/src/corpus/templates/marketplace/index.md +76 -0
  215. package/src/corpus/templates/membership-site/AGENTS.md +160 -0
  216. package/src/corpus/templates/membership-site/README.md +18 -0
  217. package/src/corpus/templates/membership-site/cloudgrid.yaml +236 -0
  218. package/src/corpus/templates/membership-site/index.md +66 -0
  219. package/src/corpus/templates/monitoring-dashboard/README.md +84 -0
  220. package/src/corpus/templates/monitoring-dashboard/cloudgrid.yaml +233 -0
  221. package/src/corpus/templates/monitoring-dashboard/index.md +328 -0
  222. package/src/corpus/templates/monitoring-dashboard/services/web/app/api/checks/route.js +76 -0
  223. package/src/corpus/templates/monitoring-dashboard/services/web/app/check-form.js +124 -0
  224. package/src/corpus/templates/monitoring-dashboard/services/web/app/layout.js +44 -0
  225. package/src/corpus/templates/monitoring-dashboard/services/web/app/page.js +49 -0
  226. package/src/corpus/templates/monitoring-dashboard/services/web/lib/db.js +32 -0
  227. package/src/corpus/templates/monitoring-dashboard/services/web/package.json +16 -0
  228. package/src/corpus/templates/online-store/AGENTS.md +153 -0
  229. package/src/corpus/templates/online-store/README.md +16 -0
  230. package/src/corpus/templates/online-store/cloudgrid.yaml +234 -0
  231. package/src/corpus/templates/online-store/index.md +81 -0
  232. package/src/corpus/templates/portfolio/README.md +29 -0
  233. package/src/corpus/templates/portfolio/cloudgrid.yaml +228 -0
  234. package/src/corpus/templates/portfolio/index.html +126 -0
  235. package/src/corpus/templates/portfolio/index.md +28 -0
  236. package/src/corpus/templates/product-catalog/README.md +74 -0
  237. package/src/corpus/templates/product-catalog/cloudgrid.yaml +232 -0
  238. package/src/corpus/templates/product-catalog/index.md +330 -0
  239. package/src/corpus/templates/product-catalog/services/web/app/api/products/route.js +69 -0
  240. package/src/corpus/templates/product-catalog/services/web/app/catalog.js +153 -0
  241. package/src/corpus/templates/product-catalog/services/web/app/layout.js +49 -0
  242. package/src/corpus/templates/product-catalog/services/web/app/page.js +36 -0
  243. package/src/corpus/templates/product-catalog/services/web/lib/db.js +32 -0
  244. package/src/corpus/templates/product-catalog/services/web/package.json +16 -0
  245. package/src/corpus/templates/product-launch/README.md +46 -0
  246. package/src/corpus/templates/product-launch/cloudgrid.yaml +234 -0
  247. package/src/corpus/templates/product-launch/index.html +320 -0
  248. package/src/corpus/templates/product-launch/index.md +34 -0
  249. package/src/corpus/templates/project-management/README.md +83 -0
  250. package/src/corpus/templates/project-management/cloudgrid.yaml +233 -0
  251. package/src/corpus/templates/project-management/index.md +346 -0
  252. package/src/corpus/templates/project-management/services/web/app/api/projects/route.js +48 -0
  253. package/src/corpus/templates/project-management/services/web/app/api/tasks/route.js +85 -0
  254. package/src/corpus/templates/project-management/services/web/app/board.js +182 -0
  255. package/src/corpus/templates/project-management/services/web/app/layout.js +45 -0
  256. package/src/corpus/templates/project-management/services/web/app/page.js +49 -0
  257. package/src/corpus/templates/project-management/services/web/lib/db.js +32 -0
  258. package/src/corpus/templates/project-management/services/web/package.json +16 -0
  259. package/src/corpus/templates/property-listings/README.md +76 -0
  260. package/src/corpus/templates/property-listings/cloudgrid.yaml +233 -0
  261. package/src/corpus/templates/property-listings/index.md +335 -0
  262. package/src/corpus/templates/property-listings/services/web/app/api/properties/route.js +73 -0
  263. package/src/corpus/templates/property-listings/services/web/app/layout.js +45 -0
  264. package/src/corpus/templates/property-listings/services/web/app/listings.js +152 -0
  265. package/src/corpus/templates/property-listings/services/web/app/page.js +53 -0
  266. package/src/corpus/templates/property-listings/services/web/lib/db.js +32 -0
  267. package/src/corpus/templates/property-listings/services/web/package.json +16 -0
  268. package/src/corpus/templates/quiz-platform/README.md +84 -0
  269. package/src/corpus/templates/quiz-platform/cloudgrid.yaml +233 -0
  270. package/src/corpus/templates/quiz-platform/index.md +313 -0
  271. package/src/corpus/templates/quiz-platform/services/web/app/api/questions/route.js +69 -0
  272. package/src/corpus/templates/quiz-platform/services/web/app/layout.js +47 -0
  273. package/src/corpus/templates/quiz-platform/services/web/app/page.js +37 -0
  274. package/src/corpus/templates/quiz-platform/services/web/app/quiz.js +188 -0
  275. package/src/corpus/templates/quiz-platform/services/web/lib/db.js +32 -0
  276. package/src/corpus/templates/quiz-platform/services/web/package.json +16 -0
  277. package/src/corpus/templates/report/cloudgrid.yaml +228 -4
  278. package/src/corpus/templates/report/index.md +3 -5
  279. package/src/corpus/templates/restaurant-reservations/AGENTS.md +258 -0
  280. package/src/corpus/templates/restaurant-reservations/README.md +17 -0
  281. package/src/corpus/templates/restaurant-reservations/cloudgrid.yaml +258 -0
  282. package/src/corpus/templates/restaurant-reservations/index.md +62 -0
  283. package/src/corpus/templates/revenue-dashboard/README.md +75 -0
  284. package/src/corpus/templates/revenue-dashboard/cloudgrid.yaml +233 -0
  285. package/src/corpus/templates/revenue-dashboard/index.md +307 -0
  286. package/src/corpus/templates/revenue-dashboard/services/web/app/api/sales/route.js +60 -0
  287. package/src/corpus/templates/revenue-dashboard/services/web/app/layout.js +40 -0
  288. package/src/corpus/templates/revenue-dashboard/services/web/app/page.js +87 -0
  289. package/src/corpus/templates/revenue-dashboard/services/web/app/sale-form.js +63 -0
  290. package/src/corpus/templates/revenue-dashboard/services/web/lib/db.js +32 -0
  291. package/src/corpus/templates/revenue-dashboard/services/web/package.json +16 -0
  292. package/src/corpus/templates/saas-marketing/README.md +30 -0
  293. package/src/corpus/templates/saas-marketing/cloudgrid.yaml +228 -0
  294. package/src/corpus/templates/saas-marketing/index.html +212 -0
  295. package/src/corpus/templates/saas-marketing/index.md +28 -0
  296. package/src/corpus/templates/status-page/README.md +28 -0
  297. package/src/corpus/templates/status-page/cloudgrid.yaml +228 -0
  298. package/src/corpus/templates/status-page/index.html +117 -0
  299. package/src/corpus/templates/status-page/index.md +28 -0
  300. package/src/corpus/templates/subscription-management/AGENTS.md +191 -0
  301. package/src/corpus/templates/subscription-management/README.md +21 -0
  302. package/src/corpus/templates/subscription-management/cloudgrid.yaml +236 -0
  303. package/src/corpus/templates/subscription-management/index.md +73 -0
  304. package/src/corpus/templates/task-manager/README.md +72 -0
  305. package/src/corpus/templates/task-manager/cloudgrid.yaml +233 -0
  306. package/src/corpus/templates/task-manager/index.md +71 -0
  307. package/src/corpus/templates/task-manager/services/web/app/api/tasks/route.js +77 -0
  308. package/src/corpus/templates/task-manager/services/web/app/layout.js +39 -0
  309. package/src/corpus/templates/task-manager/services/web/app/page.js +33 -0
  310. package/src/corpus/templates/task-manager/services/web/app/task-list.js +110 -0
  311. package/src/corpus/templates/task-manager/services/web/lib/db.js +32 -0
  312. package/src/corpus/templates/task-manager/services/web/package.json +16 -0
  313. package/src/corpus/templates/ticket-system/README.md +71 -0
  314. package/src/corpus/templates/ticket-system/cloudgrid.yaml +233 -0
  315. package/src/corpus/templates/ticket-system/index.md +68 -0
  316. package/src/corpus/templates/ticket-system/services/web/app/api/tickets/route.js +81 -0
  317. package/src/corpus/templates/ticket-system/services/web/app/layout.js +36 -0
  318. package/src/corpus/templates/ticket-system/services/web/app/page.js +35 -0
  319. package/src/corpus/templates/ticket-system/services/web/app/ticket-queue.js +112 -0
  320. package/src/corpus/templates/ticket-system/services/web/lib/db.js +32 -0
  321. package/src/corpus/templates/ticket-system/services/web/package.json +16 -0
  322. package/src/corpus/templates/time-tracking/README.md +81 -0
  323. package/src/corpus/templates/time-tracking/cloudgrid.yaml +233 -0
  324. package/src/corpus/templates/time-tracking/index.md +298 -0
  325. package/src/corpus/templates/time-tracking/services/web/app/api/entries/route.js +66 -0
  326. package/src/corpus/templates/time-tracking/services/web/app/entry-form.js +106 -0
  327. package/src/corpus/templates/time-tracking/services/web/app/layout.js +39 -0
  328. package/src/corpus/templates/time-tracking/services/web/app/page.js +30 -0
  329. package/src/corpus/templates/time-tracking/services/web/lib/db.js +32 -0
  330. package/src/corpus/templates/time-tracking/services/web/package.json +16 -0
  331. package/src/corpus/templates/travel-booking/AGENTS.md +207 -0
  332. package/src/corpus/templates/travel-booking/README.md +17 -0
  333. package/src/corpus/templates/travel-booking/cloudgrid.yaml +249 -0
  334. package/src/corpus/templates/travel-booking/index.md +88 -0
  335. package/src/corpus/templates/waitlist/README.md +38 -0
  336. package/src/corpus/templates/waitlist/cloudgrid.yaml +228 -0
  337. package/src/corpus/templates/waitlist/index.html +69 -0
  338. package/src/corpus/templates/waitlist/index.md +39 -0
  339. package/src/corpus/templates/web-app/cloudgrid.yaml +228 -4
  340. package/src/corpus/templates/web-app/index.md +3 -5
  341. package/src/corpus/workflows/admin-dashboard.md +102 -0
  342. package/src/corpus/workflows/ai-knowledge-base.md +137 -0
  343. package/src/corpus/workflows/analytics-dashboard.md +104 -0
  344. package/src/corpus/workflows/api-dashboard.md +102 -0
  345. package/src/corpus/workflows/api-docs.md +36 -0
  346. package/src/corpus/workflows/appointment-booking.md +143 -0
  347. package/src/corpus/workflows/approval-workflow.md +124 -0
  348. package/src/corpus/workflows/billing-dashboard.md +120 -0
  349. package/src/corpus/workflows/blog-cms.md +104 -0
  350. package/src/corpus/workflows/booking-system.md +116 -0
  351. package/src/corpus/workflows/calendar-scheduler.md +134 -0
  352. package/src/corpus/workflows/changelog.md +33 -0
  353. package/src/corpus/workflows/company-website.md +46 -0
  354. package/src/corpus/workflows/course-platform.md +126 -0
  355. package/src/corpus/workflows/crm.md +101 -0
  356. package/src/corpus/workflows/directory.md +101 -0
  357. package/src/corpus/workflows/docs-site.md +35 -0
  358. package/src/corpus/workflows/erp.md +125 -0
  359. package/src/corpus/workflows/event-board.md +102 -0
  360. package/src/corpus/workflows/expense-tracker.md +102 -0
  361. package/src/corpus/workflows/feature-request-board.md +105 -0
  362. package/src/corpus/workflows/financial-dashboard.md +103 -0
  363. package/src/corpus/workflows/forum.md +128 -0
  364. package/src/corpus/workflows/hr-portal.md +115 -0
  365. package/src/corpus/workflows/internal-tools-portal.md +125 -0
  366. package/src/corpus/workflows/inventory.md +101 -0
  367. package/src/corpus/workflows/invoice.md +101 -0
  368. package/src/corpus/workflows/job-board.md +101 -0
  369. package/src/corpus/workflows/kanban.md +102 -0
  370. package/src/corpus/workflows/lms.md +113 -0
  371. package/src/corpus/workflows/marketplace.md +123 -0
  372. package/src/corpus/workflows/membership-site.md +128 -0
  373. package/src/corpus/workflows/monitoring-dashboard.md +104 -0
  374. package/src/corpus/workflows/online-store.md +114 -0
  375. package/src/corpus/workflows/portfolio.md +35 -0
  376. package/src/corpus/workflows/product-catalog.md +105 -0
  377. package/src/corpus/workflows/product-launch.md +43 -0
  378. package/src/corpus/workflows/project-management.md +106 -0
  379. package/src/corpus/workflows/property-listings.md +101 -0
  380. package/src/corpus/workflows/quiz-platform.md +105 -0
  381. package/src/corpus/workflows/restaurant-reservations.md +123 -0
  382. package/src/corpus/workflows/revenue-dashboard.md +102 -0
  383. package/src/corpus/workflows/saas-marketing.md +37 -0
  384. package/src/corpus/workflows/status-page.md +35 -0
  385. package/src/corpus/workflows/subscription-management.md +141 -0
  386. package/src/corpus/workflows/task-manager.md +101 -0
  387. package/src/corpus/workflows/ticket-system.md +101 -0
  388. package/src/corpus/workflows/time-tracking.md +104 -0
  389. package/src/corpus/workflows/travel-booking.md +115 -0
  390. package/src/corpus/workflows/waitlist.md +42 -0
@@ -0,0 +1,237 @@
1
+ # ============================================================================
2
+ # cloudgrid.yaml — Complete Example
3
+ # ============================================================================
4
+ #
5
+ # This file shows EVERY field the platform supports, with comments explaining
6
+ # each one. It is a reference — no real project would use all of these at once.
7
+ #
8
+ # STANDARD: every CloudGrid template ships its cloudgrid.yaml in THIS full form.
9
+ # Uncomment ONLY the fields the archetype needs (always: name + services; plus
10
+ # needs: for runtime apps). Leave everything else commented. Comments are
11
+ # ignored by the parser, so the file deploys to exactly the active fields.
12
+ #
13
+ # Only two fields are required: name and services. Everything else is optional.
14
+ # Full docs: docs/cloudgrid-yaml-reference.md
15
+ # ============================================================================
16
+
17
+
18
+ # ─── IDENTITY ───────────────────────────────────────────────────────────────
19
+
20
+ # Entity slug (REQUIRED). 2-42 chars, lowercase alphanumeric + hyphens.
21
+ # Must start and end with a letter or digit.
22
+ # Becomes part of your public URL: <name>-<4hex>.<org>.cloudgrid.io
23
+ name: approval-workflow
24
+
25
+ # One-line summary. Max 280 chars. If omitted, Grid Brain auto-generates one.
26
+ # description: Order processing API for the e-commerce platform
27
+
28
+ # Single emoji or short text shown as the entity icon. Max 64 chars.
29
+ # icon: "📦"
30
+
31
+ # Entity type: 'app' (default) or 'agent'. An agent is an app with an agent: block.
32
+ # kind: app
33
+
34
+
35
+ # ─── NETWORKING ─────────────────────────────────────────────────────────────
36
+
37
+ # Whether this entity serves public HTTP traffic.
38
+ # true = public URL + Ingress (default). false = internal only.
39
+ # expose: true
40
+
41
+ # Additional domain names this entity serves on (the platform URL is always active).
42
+ # custom_domains:
43
+ # - orders.example.com
44
+ # - shop.example.com
45
+
46
+
47
+ # ─── HEALTH PROBE (entity-level override) ──────────────────────────────────
48
+
49
+ # Override the default health check for the entire entity.
50
+ # probe:
51
+ # path: /healthz # HTTP path to probe (default: /).
52
+ # expected: "<500" # '<500' (default), '200', '2xx'.
53
+
54
+
55
+ # ─── DEPLOY NOTIFICATIONS ──────────────────────────────────────────────────
56
+
57
+ # Slack notification to the org's default channel on deploy failure.
58
+ # true = notify (default), false = silent.
59
+ # notify: true
60
+
61
+
62
+ # ─── SCALING ────────────────────────────────────────────────────────────────
63
+
64
+ # Replica scaling intent.
65
+ # 'auto' — platform decides from the grid tier (default).
66
+ # 'alert' — single-replica, emit a SPOF warning at plug time.
67
+ # 1-10 — explicit replica count, clamped to the grid max.
68
+ # scale: auto
69
+
70
+
71
+ # ─── INFRASTRUCTURE NEEDS ──────────────────────────────────────────────────
72
+ #
73
+ # Declare infrastructure; the platform provisions it and injects connection
74
+ # details as env vars. Nine needs: database, cache, kv, queue, pubsub, vector,
75
+ # object_storage, disk, ai. Simplest form is `true`.
76
+ #
77
+ # needs:
78
+ # # database — MongoDB. Injects DATABASE_MONGODB_URL (+ legacy MONGODB_URL).
79
+ # # true | pool | dedicated | { tier: external, secret: MY_DB }
80
+ # database: true
81
+ # # cache — Redis, LRU eviction (derived data). Injects CACHE_REDIS_URL (+ REDIS_URL).
82
+ # # true | redis | { engine: external, secret: MY_REDIS_URL }
83
+ # cache: true
84
+ # # kv — Redis, no eviction (durable: flags, idempotency). Injects KV_REDIS_URL.
85
+ # kv: true
86
+ # # queue — Redis job-queue substrate (BullMQ). Injects QUEUE_REDIS_URL.
87
+ # queue: true
88
+ # # pubsub — Redis broadcast pub/sub. Injects PUBSUB_REDIS_URL.
89
+ # pubsub: true
90
+ # # vector — pgvector on Postgres. Injects VECTOR_PGVECTOR_URL (+ PGVECTOR_URL).
91
+ # # true | pgvector | { engine: pgvector, dim: 1536 }
92
+ # vector: pgvector
93
+ # # object_storage — GCS bucket. Injects OBJECT_STORAGE_GCS_BUCKET, _GCS_REGION.
94
+ # # true | { size: 10Gi }
95
+ # object_storage: true
96
+ # # disk — persistent FS mount (PVC). Injects DISK_PATH. Pins to 1 replica.
97
+ # # true | { size: 1Gi, mount: /var/data } (forbidden: /proc /sys /dev)
98
+ # disk: true
99
+ # # ai — AI Gateway via @cloudgrid-io/ai. Injects AI_GATEWAY_URL. true | false.
100
+ # ai: true
101
+
102
+
103
+ # ─── INTER-ENTITY COMMUNICATION ────────────────────────────────────────────
104
+
105
+ # Entities this app calls (outbound). Service-account token injected per pair.
106
+ # calls:
107
+ # - org:atomic/billing-api
108
+
109
+ # Inbound caller policy — who can call YOUR entity.
110
+ # callers:
111
+ # policy: auto # 'auto' | 'manual' (default).
112
+ # scope: org # 'org' (default) | 'space' | 'explicit'.
113
+ # fallback: deny # 'deny' (default) | 'warn'.
114
+ # # allowed_apps: # required only when scope: explicit
115
+ # # - org:atomic/frontend
116
+
117
+
118
+ # ─── VAULT ──────────────────────────────────────────────────────────────────
119
+ #
120
+ # Map org vault items to env vars. Keys UPPER_SNAKE_CASE; values = vault item keys.
121
+ # This approval-workflow signs approvers in with an auth provider (Clerk/Auth0).
122
+ # Uncomment the vault block below and store the real key with `grid secrets set`
123
+ # so the deployer injects it as an env var — never hardcode provider keys.
124
+ # vault:
125
+ # AUTH_PROVIDER_KEY: auth-provider-secret-key
126
+ # # Add SENDGRID_API_KEY: sendgrid-key for email approval notifications, or
127
+ # # STRIPE_KEY: stripe-live-key if an approval gates a payment/checkout.
128
+
129
+
130
+ # ─── CONNECTORS AND HOOKS ──────────────────────────────────────────────────
131
+
132
+ # connectors:
133
+ # - id: team-slack
134
+ # target: org # 'system' | 'org'.
135
+ # channel: "#deploys"
136
+ # hooks:
137
+ # - on: deploy.failed # release.published | deploy.failed | feedback.received | entity.created
138
+ # via: team-slack
139
+ # template: "Deploy failed for {entity_name}: {error}"
140
+ # channel: "#alerts"
141
+ # triggers:
142
+ # - from: team-slack
143
+ # event: message
144
+ # channel: "#support"
145
+ # route: /webhooks/slack
146
+
147
+
148
+ # ─── LOCAL DEVELOPMENT ──────────────────────────────────────────────────────
149
+
150
+ # Config for `grid dev`. Redact fields in dev data snapshots.
151
+ # dev:
152
+ # snapshot:
153
+ # mask:
154
+ # - users.email
155
+ # - users.phone
156
+
157
+
158
+ # ─── AGENT METADATA ────────────────────────────────────────────────────────
159
+
160
+ # An agent is an app with kind: agent (above) and an agent: block.
161
+ # agent:
162
+ # purpose: Sync customer data from external CRM every night
163
+ # schedule: "0 2 * * *"
164
+ # trigger: webhook
165
+
166
+
167
+ # ─── PRIVATE RESOURCE AUTO-DEPENDENCIES ────────────────────────────────────
168
+
169
+ # When true (default), private resources are auto-injected as depends_on.
170
+ # auto_depends_on_private_requires: true
171
+
172
+
173
+ # ─── SERVICES (REQUIRED) ───────────────────────────────────────────────────
174
+ #
175
+ # At least one service is required. Key = service name (slug rules).
176
+ # Types: node, nextjs, python, static, cron.
177
+ #
178
+ services:
179
+ web:
180
+ # type (REQUIRED): node | nextjs | python | static | cron
181
+ type: nextjs
182
+ # HTTP route: '/' | '/api' | false (internal) | omitted (=false + warning).
183
+ # Only one service per entity can claim '/'.
184
+ path: /
185
+ # Container port (default 8080; read process.env.PORT). Not for cron.
186
+ # port: 3000
187
+ # nextjs only: base_image: distroless (default) | alpine
188
+ # base_image: distroless
189
+ # node only: lang: javascript (default) | typescript
190
+ # lang: typescript
191
+ # Custom source location (default services/<name>/). '.' = project root.
192
+ # source:
193
+ # path: src/worker
194
+ # Health probe: false/omitted (TCP) | true (/health) | "/path" | {path,expected}
195
+ # health:
196
+ # path: /api/health
197
+ # expected: "200"
198
+ # Static runtime env vars (strings). Reserved: PORT, APP_NAME, SERVICE_NAME,
199
+ # NODE_ENV, MONGODB_URL, REDIS_URL, AI_GATEWAY_URL, N8N_WEBHOOK_URL, CLOUDGRID_*.
200
+ # env:
201
+ # LOG_LEVEL: info
202
+ # Sibling services/private resources that must be Ready first (no cron, no cycles).
203
+ # depends_on:
204
+ # - worker
205
+ # Per-service needs override (merges with app-level needs).
206
+ # needs:
207
+ # queue: true
208
+ # Static-only build step:
209
+ # build:
210
+ # command: npm run build
211
+ # output: dist
212
+ # env:
213
+ # VITE_API_URL: https://api.example.com
214
+ # node_version: "22" # static build step: '18'|'20'|'22'|'24' (quoted)
215
+ # Cron-only: schedule (REQUIRED), timezone (UTC|EST|PST), run (job | https URL)
216
+ # schedule: "0 9 * * 1"
217
+ # timezone: UTC
218
+ # run: job
219
+ # Verbose per-service persistence (prefer needs.disk):
220
+ # persist:
221
+ # - name: scratch
222
+ # path: /tmp/scratch
223
+ # size: 500Mi
224
+
225
+
226
+
227
+ needs:
228
+ database: true
229
+
230
+
231
+ # ============================================================================
232
+ # NOTES
233
+ # - NOT here: org:/entity_id: (→ .cloudgrid/link.json), secrets (→ grid secrets set),
234
+ # Dockerfile (platform generates from services.*.type).
235
+ # - Deploy: grid plug | Local with grid resources: grid dev
236
+ # - Full reference: docs/cloudgrid-yaml-reference.md | CLI: docs/cli-reference.md
237
+ # ============================================================================
@@ -0,0 +1,58 @@
1
+ # Template: approval-workflow (blueprint — Next.js + Mongo)
2
+
3
+ A multi-step approval system: a requester submits a **request**, it advances
4
+ through an ordered chain of **approval steps** decided by assigned **roles**
5
+ (approve / reject / delegate), every action lands in an append-only **audit**
6
+ log, and approvers are notified as each step activates. Persistent Next.js +
7
+ Mongo runtime app (`needs: { database: true }`), extending the proven
8
+ `app-with-data` shape with a state machine, auth-provider roles, and
9
+ notifications.
10
+
11
+ **This is a BLUEPRINT — structure + cloudgrid.yaml, not shipped app code.**
12
+ Read `AGENTS.md` (fetch this bundle) for the file tree, collections, state
13
+ machine, and CloudGrid wiring, then build the app under `services/web/`.
14
+
15
+ ## Fetch bundle
16
+
17
+ - `gridctl_fetch("template", "approval-workflow")` → this blueprint:
18
+ - `AGENTS.md` — file tree, Mongo collections (`users`, `requests`, `steps`,
19
+ `audit`), the state machine, auth/payments wiring, deploy steps, edition note.
20
+ - `cloudgrid.yaml` — the full-annotated reference with only `name`,
21
+ `services.web { type: nextjs, path: / }`, and `needs: { database: true }`
22
+ active, plus a commented `vault:` block for `AUTH_PROVIDER_KEY`.
23
+ - `README.md` — one-paragraph what/why.
24
+ - `gridctl_fetch("template", "app-with-data")` → the concrete Next.js + Mongo
25
+ CRUD wiring (lazy `lib/db.js`, App Router route, server page) to adapt from.
26
+
27
+ ## Key rules
28
+
29
+ 1. **Blueprint, not code** — read `AGENTS.md` and build; nothing ships here to run.
30
+ 2. **Service code lives under `services/web/`.** `path: /` is the URL mount, NOT
31
+ the filesystem path.
32
+ 3. **Declare `needs: { database: true }`** (the canonical shape). The deployer
33
+ provisions Mongo and injects `DATABASE_MONGODB_URL` (plus the legacy
34
+ `MONGODB_URL` alias). Never set `needs:` and `requires:` together; never
35
+ author `requires:`.
36
+ 4. **Read the DB string lazily** inside the `getDb` getter
37
+ (`process.env.DATABASE_MONGODB_URL || process.env.MONGODB_URL`), never at
38
+ module top level, or `next build` fails.
39
+ 5. **Secrets via the `vault:` block** → env vars (e.g. `AUTH_PROVIDER_KEY`,
40
+ `STRIPE_KEY`); store real values with `grid secrets set`, never hardcode.
41
+ 6. **Runtime app → local edition only.** Deploy with `grid plug` (async — poll
42
+ to a live URL). Hosted (Claude Web) can only publish static pages.
43
+
44
+ ## cloudgrid.yaml
45
+
46
+ ```yaml
47
+ # On disk this file is the full-annotated reference (templates/_cloudgrid.yaml.reference) with EVERY
48
+ # field present as a comment; only the fields below are uncommented, so it
49
+ # deploys to exactly these active fields (plus a commented vault: block to
50
+ # uncomment for the auth provider secret).
51
+ name: approval-workflow
52
+ services:
53
+ web:
54
+ type: nextjs
55
+ path: /
56
+ needs:
57
+ database: true
58
+ ```
@@ -0,0 +1,199 @@
1
+ # AGENTS.md — billing-dashboard (blueprint)
2
+
3
+ This is a **blueprint**, not runnable app code. It tells an agent exactly how to
4
+ build a working SaaS billing dashboard on CloudGrid: a Next.js app that shows
5
+ customers, invoices, and charges, meters usage, renders a revenue view, and wires
6
+ **Stripe** for real payments (checkout + a signature-verified webhook). Data lives
7
+ in the grid-shared Mongo. Read this whole file, then write the files under
8
+ `services/web/` following the tree and wiring rules below.
9
+
10
+ The proven shape to imitate is `app-with-data` (Next.js App Router + `mongodb`
11
+ driver, lazy DB getter, app under `services/web/`). This blueprint adds the
12
+ billing collections, a Stripe client, checkout + webhook + usage-sync routes, and
13
+ a revenue dashboard view.
14
+
15
+ ## 1. File tree
16
+
17
+ App code MUST live under `services/web/` — `path: /` in `cloudgrid.yaml` is the
18
+ URL mount, NOT the filesystem path. A service named `web` means the CLI looks for
19
+ `services/web/`; files at the project root fail with
20
+ `Error: Service directory not found: …/services/web`.
21
+
22
+ ```
23
+ cloudgrid.yaml # name + services.web (nextjs) + needs:{database:true} + vault:{STRIPE_KEY}
24
+ services/web/package.json # next, react, react-dom, mongodb, stripe
25
+ services/web/lib/db.js # lazy Mongo client from DATABASE_MONGODB_URL (legacy MONGODB_URL fallback)
26
+ services/web/lib/stripe.js # lazy Stripe client from process.env.STRIPE_KEY (injected by the vault: block)
27
+ services/web/lib/money.js # money helpers (all amounts are integer cents; format for display only)
28
+ services/web/app/layout.js # root layout + inline CSS (dashboard chrome / nav)
29
+ services/web/app/page.js # revenue overview: MRR, outstanding, recent invoices (server component)
30
+ services/web/app/customers/page.js # customers list (server component, reads the customers collection)
31
+ services/web/app/customers/[id]/page.js # customer detail: their invoices, charges, usage
32
+ services/web/app/invoices/page.js # invoices list + status filter
33
+ services/web/app/invoices/invoice-actions.js # "use client": create invoice, send/collect via Stripe Checkout
34
+ services/web/app/api/customers/route.js # GET (list) / POST (create) — mirror to a Stripe Customer
35
+ services/web/app/api/invoices/route.js # GET (list) / POST (create draft invoice with line items)
36
+ services/web/app/api/checkout/route.js # POST: create a Stripe Checkout Session to collect an invoice
37
+ services/web/app/api/usage/route.js # POST: record a metered-usage event for a customer/meter
38
+ services/web/app/api/webhook/route.js # POST: Stripe webhook — verify signature, mark invoices paid, record charges
39
+ ```
40
+
41
+ ## 2. Mongo collections + fields
42
+
43
+ The grid provisions one Mongo database (`needs: { database: true }`). Store **all
44
+ money as integer cents** — never floats. Suggested collections:
45
+
46
+ **`customers`**
47
+ - `_id` — ObjectId
48
+ - `name` — string
49
+ - `email` — string (unique per org)
50
+ - `stripeCustomerId` — string (the `cus_…` id from Stripe; link, don't duplicate)
51
+ - `plan` — string (e.g. `"free"`, `"pro"`, `"enterprise"`) — optional
52
+ - `createdAt` — Date
53
+
54
+ **`invoices`**
55
+ - `_id` — ObjectId
56
+ - `customerId` — ObjectId ref → `customers`
57
+ - `number` — string (human invoice number, e.g. `"INV-1042"`)
58
+ - `lineItems` — array of `{ description, quantity, unitAmountCents }`
59
+ - `amountDueCents` — integer (sum of line items; authoritative on the server)
60
+ - `currency` — string, e.g. `"usd"`
61
+ - `status` — string: `"draft"` → `"open"` → `"paid"` / `"void"` (set to
62
+ `paid` ONLY by the webhook)
63
+ - `stripeSessionId` — string (Checkout Session id used to collect it; idempotency key)
64
+ - `dueDate` — Date
65
+ - `createdAt` — Date
66
+
67
+ **`charges`**
68
+ - `_id` — ObjectId
69
+ - `customerId` — ObjectId ref → `customers`
70
+ - `invoiceId` — ObjectId ref → `invoices` (nullable for one-off charges)
71
+ - `amountCents` — integer (authoritative total from the verified Stripe event)
72
+ - `currency` — string
73
+ - `stripePaymentId` — string (`pi_…` / `ch_…`; unique — idempotency)
74
+ - `status` — string: `"succeeded"` / `"refunded"`
75
+ - `createdAt` — Date
76
+
77
+ **`usage_events`** (metering → revenue)
78
+ - `_id` — ObjectId
79
+ - `customerId` — ObjectId ref → `customers`
80
+ - `meter` — string (e.g. `"api_calls"`, `"seats"`, `"gb_egress"`)
81
+ - `quantity` — number
82
+ - `ts` — Date (event time; aggregate per billing period)
83
+
84
+ Derive the revenue view by aggregating: **MRR / period revenue** from `charges`
85
+ with `status: "succeeded"`, **outstanding** from `invoices` with `status: "open"`,
86
+ and **usage** rolled up from `usage_events` per `customerId` + `meter` for the
87
+ current period. Never trust amounts sent by the browser — the checkout route
88
+ builds line items from the server-side `invoices` doc, and the webhook records the
89
+ total from the verified Stripe event.
90
+
91
+ ## 3. How CloudGrid injects things (do NOT hardcode any of this)
92
+
93
+ - **Mongo:** declare `needs: { database: true }`. The platform provisions Mongo
94
+ and injects the connection string as **`DATABASE_MONGODB_URL`** (plus the legacy
95
+ **`MONGODB_URL`** alias) at dev-time (`grid dev`) and at runtime (after
96
+ `grid plug`). Read it as `process.env.DATABASE_MONGODB_URL || process.env.MONGODB_URL`
97
+ **lazily inside a getter**, never at module top level — a top-level read fails
98
+ `next build`, which imports the module for route analysis before the grid injects
99
+ the var. Never hardcode a connection string; never commit a secret.
100
+ - **Stripe secret:** put it in the vault, not in code. The `vault:` block in
101
+ `cloudgrid.yaml` maps the vault item `stripe-live-key` to the env var
102
+ **`STRIPE_KEY`**. Set the vault item once with `grid secrets set stripe-live-key`
103
+ (paste the `sk_live_…` / `sk_test_…` key); the platform injects it as
104
+ `process.env.STRIPE_KEY`. Read it lazily in `services/web/lib/stripe.js`.
105
+ - **Stripe webhook signing secret:** the `whsec_…` value Stripe gives you for the
106
+ webhook endpoint. Add it to the vault and map it in the `vault:` block, e.g.
107
+ `STRIPE_WEBHOOK_SECRET: stripe-webhook-secret`, then verify events with
108
+ `stripe.webhooks.constructEvent(rawBody, sig, process.env.STRIPE_WEBHOOK_SECRET)`.
109
+ - **Public base URL:** Stripe Checkout needs absolute `success_url` / `cancel_url`.
110
+ Derive them from the incoming request (`new URL(request.url).origin`) rather than
111
+ hardcoding the live host, so it works in `grid dev` and after `grid plug`.
112
+ - **Secrets via vault → env vars, non-secret config via env:** any provider key
113
+ (Stripe, an auth provider, an email sender) goes in the vault and is mapped in
114
+ `vault:`; non-secret flags (log level, default currency) can be plain
115
+ `services.web.env` entries or `grid env`.
116
+ - **AI (only if you add it, e.g. an AI usage-forecast):** declare
117
+ `needs: { ai: true }` and the platform injects **`AI_GATEWAY_URL`**; call it via
118
+ `@cloudgrid-io/ai`. Not required for a billing dashboard.
119
+
120
+ ## 4. Wiring payments (Stripe) — and optional auth
121
+
122
+ **Create-invoice + checkout (`app/api/invoices/route.js`, `app/api/checkout/route.js`):**
123
+ 1. Create a `draft` invoice server-side from `lineItems`; compute
124
+ `amountDueCents` as the sum of `quantity * unitAmountCents` — never trust a
125
+ total sent by the browser.
126
+ 2. To collect it, `POST /api/checkout` with the `invoiceId`. Load the invoice from
127
+ Mongo, build Stripe `line_items` with `price_data` from the stored line items
128
+ (`unit_amount: unitAmountCents`, `currency`).
129
+ 3. `stripe.checkout.sessions.create({ mode: "payment", customer: <stripeCustomerId>,
130
+ line_items, metadata: { invoiceId }, success_url: origin +
131
+ "/invoices?paid={CHECKOUT_SESSION_ID}", cancel_url: origin + "/invoices" })`.
132
+ 4. Save `stripeSessionId` on the invoice, set `status: "open"`, return
133
+ `{ url: session.url }`; the client redirects to it.
134
+
135
+ **Webhook (`app/api/webhook/route.js`):**
136
+ 1. Read the **raw** body — in the App Router use `await request.text()`, do NOT
137
+ `request.json()`; signature verification needs the exact bytes.
138
+ 2. Verify with `stripe.webhooks.constructEvent(rawBody,
139
+ request.headers.get("stripe-signature"), process.env.STRIPE_WEBHOOK_SECRET)`.
140
+ 3. On `checkout.session.completed`: find the invoice by `metadata.invoiceId` (or
141
+ `stripeSessionId`), set `status: "paid"`, and insert a `charges` doc with the
142
+ authoritative `amountCents = event.data.object.amount_total` and the payment id
143
+ — upsert by `stripePaymentId` so retries are idempotent.
144
+ 4. On `charge.refunded`: mark the matching `charges` doc `refunded`.
145
+ 5. Return `200` fast; return `400` if verification fails. Register the endpoint URL
146
+ (`<live-url>/api/webhook`) in the Stripe dashboard and copy its `whsec_…` secret
147
+ into the vault.
148
+
149
+ **Usage metering (`app/api/usage/route.js`):** `POST { customerId, meter, quantity }`
150
+ inserts a `usage_events` doc. Aggregate per period for the revenue view (and, if you
151
+ use Stripe metered prices, forward the quantity with
152
+ `stripe.billing.meterEvents.create(...)`).
153
+
154
+ **Optional auth (protect the dashboard / per-customer portal):** add a provider SDK
155
+ (Clerk, Auth0, or NextAuth). Put its keys in the vault and map them in the `vault:`
156
+ block, e.g. `AUTH_PROVIDER_KEY: clerk-secret-key` (plus any publishable key), read
157
+ them from `process.env`, and gate the dashboard pages behind the provider's
158
+ middleware. A billing dashboard is internal/admin, so add auth before exposing it
159
+ publicly.
160
+
161
+ ## 5. Deploy steps
162
+
163
+ 1. `grid init` an app `<name>` (creates the entity + `.cloudgrid/link.json`, writes
164
+ a `cloudgrid.yaml` with empty `services: {}`). Run this FIRST — `plug` needs a
165
+ linked directory.
166
+ 2. Write the app under `services/web/` and set `cloudgrid.yaml` to the shape in this
167
+ template (name + `services.web` nextjs + `needs: { database: true }` + the
168
+ `vault: { STRIPE_KEY: stripe-live-key }` block).
169
+ 3. `grid secrets set stripe-live-key` (and `stripe-webhook-secret` once you map it)
170
+ so the vault items the `vault:` block references exist. Do NOT set
171
+ `DATABASE_MONGODB_URL` yourself — the grid injects it.
172
+ 4. (Optional) `grid dev` to run locally against the injected Mongo + your Stripe
173
+ test key before deploying.
174
+ 5. `grid plug` to build + deploy. A runtime deploy is **async**: `plug` returns
175
+ `status: building`. Poll `grid status` until the entity is live; surface a
176
+ liveness signal, never a bare silent wait. Only then return the live app URL.
177
+ 6. Register `<live-url>/api/webhook` in the Stripe dashboard, copy its `whsec_…`
178
+ into the vault, and re-`grid plug` the SAME entity (same URL) if you changed the
179
+ `vault:` mapping.
180
+
181
+ ## 6. Edition note
182
+
183
+ This is a **runtime app** (a built + deployed container), so it needs the **local
184
+ edition** (Claude Desktop / Claude Code) or the CloudGrid CLI. The hosted edition
185
+ (Claude Web / hosted MCP) is inline-only and can publish only static pages — it
186
+ cannot build this dashboard. If you are on hosted, offer a static revenue-view
187
+ mockup instead and stop the runtime path.
188
+
189
+ ## 7. Self-check before you call it done
190
+
191
+ - App code is under `services/web/`, not the root.
192
+ - DB and Stripe clients are read LAZILY inside getters, never at module top level.
193
+ - All money is stored as integer cents; the revenue view aggregates from `charges`
194
+ / `invoices` / `usage_events` server-side.
195
+ - Invoice totals are computed server-side; the webhook records the Stripe total and
196
+ reads the RAW request body to verify the signature.
197
+ - `cloudgrid.yaml` active fields are exactly: `name`, `services.web {type:nextjs,
198
+ path:/}`, `needs: { database: true }`, and the `vault:` block for `STRIPE_KEY`.
199
+ - No secret or connection string is committed anywhere.
@@ -0,0 +1,18 @@
1
+ # billing-dashboard template — SaaS billing blueprint (Next.js + Mongo + Stripe)
2
+
3
+ A **blueprint** for a real SaaS billing dashboard on CloudGrid: a Next.js app that
4
+ tracks `customers`, `invoices`, `charges`, and `usage_events` in the grid-shared
5
+ Mongo, meters usage, renders a revenue view (MRR / outstanding / recent invoices),
6
+ and wires **Stripe** the CloudGrid-correct way — checkout to collect invoices and a
7
+ signature-verified webhook that marks them paid and records charges. It is the same
8
+ proven `services/web/` + lazy-Mongo shape as `app-with-data`, plus payments. It
9
+ exists because "build a billing / invoicing dashboard" needs a database *and* a
10
+ payment provider wired correctly (Mongo via `needs`, the Stripe key via the
11
+ `vault:` block → `STRIPE_KEY`), and getting that wiring right is the hard part.
12
+
13
+ **This is a blueprint: structure + `cloudgrid.yaml`, adapt and build — not finished
14
+ app code.** Read `AGENTS.md` for the file tree, the Mongo collections/fields, how
15
+ the grid injects Mongo (`DATABASE_MONGODB_URL`) and the Stripe secret (`vault:` →
16
+ `STRIPE_KEY`), the checkout + webhook + usage wiring, and the deploy steps — then
17
+ build the app under `services/web/`, adapting the collections and UI to the user's
18
+ billing model.