@cloudgrid-io/mcp 0.13.0 → 0.15.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 (364) hide show
  1. package/package.json +1 -1
  2. package/src/corpus/capability-map.md +81 -7
  3. package/src/corpus/templates/_cloudgrid.yaml.reference +228 -0
  4. package/src/corpus/templates/admin-dashboard/cloudgrid.yaml +226 -8
  5. package/src/corpus/templates/admin-dashboard/index.md +3 -0
  6. package/src/corpus/templates/ai-app/cloudgrid.yaml +225 -11
  7. package/src/corpus/templates/ai-app/index.md +3 -11
  8. package/src/corpus/templates/ai-knowledge-base/AGENTS.md +254 -0
  9. package/src/corpus/templates/ai-knowledge-base/README.md +28 -0
  10. package/src/corpus/templates/ai-knowledge-base/cloudgrid.yaml +238 -0
  11. package/src/corpus/templates/ai-knowledge-base/index.md +81 -0
  12. package/src/corpus/templates/analytics-dashboard/README.md +85 -0
  13. package/src/corpus/templates/analytics-dashboard/cloudgrid.yaml +232 -0
  14. package/src/corpus/templates/analytics-dashboard/index.md +316 -0
  15. package/src/corpus/templates/analytics-dashboard/services/web/app/api/events/route.js +60 -0
  16. package/src/corpus/templates/analytics-dashboard/services/web/app/event-form.js +100 -0
  17. package/src/corpus/templates/analytics-dashboard/services/web/app/layout.js +41 -0
  18. package/src/corpus/templates/analytics-dashboard/services/web/app/page.js +54 -0
  19. package/src/corpus/templates/analytics-dashboard/services/web/lib/db.js +32 -0
  20. package/src/corpus/templates/analytics-dashboard/services/web/package.json +16 -0
  21. package/src/corpus/templates/api-dashboard/README.md +84 -0
  22. package/src/corpus/templates/api-dashboard/cloudgrid.yaml +233 -0
  23. package/src/corpus/templates/api-dashboard/index.md +310 -0
  24. package/src/corpus/templates/api-dashboard/services/web/app/api/requests/route.js +62 -0
  25. package/src/corpus/templates/api-dashboard/services/web/app/dashboard.js +156 -0
  26. package/src/corpus/templates/api-dashboard/services/web/app/layout.js +42 -0
  27. package/src/corpus/templates/api-dashboard/services/web/app/page.js +39 -0
  28. package/src/corpus/templates/api-dashboard/services/web/lib/db.js +32 -0
  29. package/src/corpus/templates/api-dashboard/services/web/package.json +16 -0
  30. package/src/corpus/templates/api-docs/cloudgrid.yaml +222 -4
  31. package/src/corpus/templates/api-docs/index.md +3 -5
  32. package/src/corpus/templates/api-service/cloudgrid.yaml +224 -9
  33. package/src/corpus/templates/api-service/index.md +3 -11
  34. package/src/corpus/templates/app-with-data/cloudgrid.yaml +226 -8
  35. package/src/corpus/templates/app-with-data/index.md +3 -8
  36. package/src/corpus/templates/appointment-booking/AGENTS.md +223 -0
  37. package/src/corpus/templates/appointment-booking/README.md +16 -0
  38. package/src/corpus/templates/appointment-booking/cloudgrid.yaml +250 -0
  39. package/src/corpus/templates/appointment-booking/index.md +72 -0
  40. package/src/corpus/templates/approval-workflow/AGENTS.md +170 -0
  41. package/src/corpus/templates/approval-workflow/README.md +12 -0
  42. package/src/corpus/templates/approval-workflow/cloudgrid.yaml +237 -0
  43. package/src/corpus/templates/approval-workflow/index.md +58 -0
  44. package/src/corpus/templates/billing-dashboard/AGENTS.md +199 -0
  45. package/src/corpus/templates/billing-dashboard/README.md +18 -0
  46. package/src/corpus/templates/billing-dashboard/cloudgrid.yaml +235 -0
  47. package/src/corpus/templates/billing-dashboard/index.md +87 -0
  48. package/src/corpus/templates/blog-cms/README.md +94 -0
  49. package/src/corpus/templates/blog-cms/cloudgrid.yaml +233 -0
  50. package/src/corpus/templates/blog-cms/index.md +358 -0
  51. package/src/corpus/templates/blog-cms/services/web/app/admin/admin-editor.js +133 -0
  52. package/src/corpus/templates/blog-cms/services/web/app/admin/page.js +33 -0
  53. package/src/corpus/templates/blog-cms/services/web/app/api/posts/route.js +84 -0
  54. package/src/corpus/templates/blog-cms/services/web/app/layout.js +47 -0
  55. package/src/corpus/templates/blog-cms/services/web/app/page.js +56 -0
  56. package/src/corpus/templates/blog-cms/services/web/app/posts/[slug]/page.js +45 -0
  57. package/src/corpus/templates/blog-cms/services/web/lib/db.js +32 -0
  58. package/src/corpus/templates/blog-cms/services/web/package.json +16 -0
  59. package/src/corpus/templates/booking-system/AGENTS.md +189 -0
  60. package/src/corpus/templates/booking-system/README.md +17 -0
  61. package/src/corpus/templates/booking-system/cloudgrid.yaml +248 -0
  62. package/src/corpus/templates/booking-system/index.md +86 -0
  63. package/src/corpus/templates/calendar-scheduler/AGENTS.md +226 -0
  64. package/src/corpus/templates/calendar-scheduler/README.md +25 -0
  65. package/src/corpus/templates/calendar-scheduler/cloudgrid.yaml +259 -0
  66. package/src/corpus/templates/calendar-scheduler/index.md +85 -0
  67. package/src/corpus/templates/changelog/cloudgrid.yaml +222 -4
  68. package/src/corpus/templates/changelog/index.md +3 -5
  69. package/src/corpus/templates/company-website/README.md +54 -0
  70. package/src/corpus/templates/company-website/cloudgrid.yaml +233 -0
  71. package/src/corpus/templates/company-website/index.html +309 -0
  72. package/src/corpus/templates/company-website/index.md +29 -0
  73. package/src/corpus/templates/course-platform/AGENTS.md +161 -0
  74. package/src/corpus/templates/course-platform/README.md +26 -0
  75. package/src/corpus/templates/course-platform/cloudgrid.yaml +237 -0
  76. package/src/corpus/templates/course-platform/index.md +70 -0
  77. package/src/corpus/templates/crm/cloudgrid.yaml +226 -8
  78. package/src/corpus/templates/crm/index.md +3 -0
  79. package/src/corpus/templates/dashboard/cloudgrid.yaml +228 -4
  80. package/src/corpus/templates/dashboard/index.md +3 -5
  81. package/src/corpus/templates/deck/cloudgrid.yaml +228 -4
  82. package/src/corpus/templates/deck/index.md +3 -5
  83. package/src/corpus/templates/directory/README.md +75 -0
  84. package/src/corpus/templates/directory/cloudgrid.yaml +233 -0
  85. package/src/corpus/templates/directory/index.md +334 -0
  86. package/src/corpus/templates/directory/services/web/app/api/entries/route.js +63 -0
  87. package/src/corpus/templates/directory/services/web/app/directory-list.js +146 -0
  88. package/src/corpus/templates/directory/services/web/app/layout.js +44 -0
  89. package/src/corpus/templates/directory/services/web/app/page.js +38 -0
  90. package/src/corpus/templates/directory/services/web/lib/db.js +32 -0
  91. package/src/corpus/templates/directory/services/web/package.json +16 -0
  92. package/src/corpus/templates/docs-site/cloudgrid.yaml +222 -4
  93. package/src/corpus/templates/docs-site/index.md +3 -5
  94. package/src/corpus/templates/erp/AGENTS.md +116 -0
  95. package/src/corpus/templates/erp/README.md +17 -0
  96. package/src/corpus/templates/erp/cloudgrid.yaml +235 -0
  97. package/src/corpus/templates/erp/index.md +81 -0
  98. package/src/corpus/templates/event-board/README.md +74 -0
  99. package/src/corpus/templates/event-board/cloudgrid.yaml +233 -0
  100. package/src/corpus/templates/event-board/index.md +299 -0
  101. package/src/corpus/templates/event-board/services/web/app/api/events/route.js +61 -0
  102. package/src/corpus/templates/event-board/services/web/app/event-form.js +118 -0
  103. package/src/corpus/templates/event-board/services/web/app/layout.js +39 -0
  104. package/src/corpus/templates/event-board/services/web/app/page.js +34 -0
  105. package/src/corpus/templates/event-board/services/web/lib/db.js +32 -0
  106. package/src/corpus/templates/event-board/services/web/package.json +16 -0
  107. package/src/corpus/templates/expense-tracker/README.md +76 -0
  108. package/src/corpus/templates/expense-tracker/cloudgrid.yaml +233 -0
  109. package/src/corpus/templates/expense-tracker/index.md +305 -0
  110. package/src/corpus/templates/expense-tracker/services/web/app/api/expenses/route.js +61 -0
  111. package/src/corpus/templates/expense-tracker/services/web/app/expense-form.js +145 -0
  112. package/src/corpus/templates/expense-tracker/services/web/app/layout.js +42 -0
  113. package/src/corpus/templates/expense-tracker/services/web/app/page.js +34 -0
  114. package/src/corpus/templates/expense-tracker/services/web/lib/db.js +32 -0
  115. package/src/corpus/templates/expense-tracker/services/web/package.json +16 -0
  116. package/src/corpus/templates/feature-request-board/README.md +87 -0
  117. package/src/corpus/templates/feature-request-board/cloudgrid.yaml +233 -0
  118. package/src/corpus/templates/feature-request-board/index.md +317 -0
  119. package/src/corpus/templates/feature-request-board/services/web/app/api/requests/route.js +92 -0
  120. package/src/corpus/templates/feature-request-board/services/web/app/board.js +91 -0
  121. package/src/corpus/templates/feature-request-board/services/web/app/layout.js +43 -0
  122. package/src/corpus/templates/feature-request-board/services/web/app/page.js +35 -0
  123. package/src/corpus/templates/feature-request-board/services/web/lib/db.js +32 -0
  124. package/src/corpus/templates/feature-request-board/services/web/package.json +16 -0
  125. package/src/corpus/templates/financial-dashboard/README.md +80 -0
  126. package/src/corpus/templates/financial-dashboard/cloudgrid.yaml +233 -0
  127. package/src/corpus/templates/financial-dashboard/index.md +326 -0
  128. package/src/corpus/templates/financial-dashboard/services/web/app/api/entries/route.js +63 -0
  129. package/src/corpus/templates/financial-dashboard/services/web/app/entry-board.js +130 -0
  130. package/src/corpus/templates/financial-dashboard/services/web/app/layout.js +46 -0
  131. package/src/corpus/templates/financial-dashboard/services/web/app/page.js +31 -0
  132. package/src/corpus/templates/financial-dashboard/services/web/lib/db.js +32 -0
  133. package/src/corpus/templates/financial-dashboard/services/web/package.json +16 -0
  134. package/src/corpus/templates/forum/AGENTS.md +196 -0
  135. package/src/corpus/templates/forum/README.md +12 -0
  136. package/src/corpus/templates/forum/cloudgrid.yaml +237 -0
  137. package/src/corpus/templates/forum/index.md +66 -0
  138. package/src/corpus/templates/hr-portal/AGENTS.md +174 -0
  139. package/src/corpus/templates/hr-portal/README.md +14 -0
  140. package/src/corpus/templates/hr-portal/cloudgrid.yaml +237 -0
  141. package/src/corpus/templates/hr-portal/index.md +56 -0
  142. package/src/corpus/templates/internal-tools-portal/AGENTS.md +201 -0
  143. package/src/corpus/templates/internal-tools-portal/README.md +17 -0
  144. package/src/corpus/templates/internal-tools-portal/cloudgrid.yaml +237 -0
  145. package/src/corpus/templates/internal-tools-portal/index.md +62 -0
  146. package/src/corpus/templates/inventory/README.md +71 -0
  147. package/src/corpus/templates/inventory/cloudgrid.yaml +233 -0
  148. package/src/corpus/templates/inventory/index.md +68 -0
  149. package/src/corpus/templates/inventory/services/web/app/api/items/route.js +88 -0
  150. package/src/corpus/templates/inventory/services/web/app/inventory-manager.js +101 -0
  151. package/src/corpus/templates/inventory/services/web/app/layout.js +36 -0
  152. package/src/corpus/templates/inventory/services/web/app/page.js +37 -0
  153. package/src/corpus/templates/inventory/services/web/lib/db.js +32 -0
  154. package/src/corpus/templates/inventory/services/web/package.json +16 -0
  155. package/src/corpus/templates/invoice/README.md +71 -0
  156. package/src/corpus/templates/invoice/cloudgrid.yaml +233 -0
  157. package/src/corpus/templates/invoice/index.md +68 -0
  158. package/src/corpus/templates/invoice/services/web/app/api/invoices/route.js +82 -0
  159. package/src/corpus/templates/invoice/services/web/app/invoice-manager.js +101 -0
  160. package/src/corpus/templates/invoice/services/web/app/layout.js +35 -0
  161. package/src/corpus/templates/invoice/services/web/app/page.js +34 -0
  162. package/src/corpus/templates/invoice/services/web/lib/db.js +32 -0
  163. package/src/corpus/templates/invoice/services/web/package.json +16 -0
  164. package/src/corpus/templates/job-board/README.md +71 -0
  165. package/src/corpus/templates/job-board/cloudgrid.yaml +233 -0
  166. package/src/corpus/templates/job-board/index.md +68 -0
  167. package/src/corpus/templates/job-board/services/web/app/api/jobs/route.js +66 -0
  168. package/src/corpus/templates/job-board/services/web/app/job-board.js +73 -0
  169. package/src/corpus/templates/job-board/services/web/app/layout.js +35 -0
  170. package/src/corpus/templates/job-board/services/web/app/page.js +32 -0
  171. package/src/corpus/templates/job-board/services/web/lib/db.js +32 -0
  172. package/src/corpus/templates/job-board/services/web/package.json +16 -0
  173. package/src/corpus/templates/kanban/cloudgrid.yaml +226 -8
  174. package/src/corpus/templates/kanban/index.md +3 -0
  175. package/src/corpus/templates/landing-page/cloudgrid.yaml +228 -4
  176. package/src/corpus/templates/landing-page/index.md +3 -5
  177. package/src/corpus/templates/lms/AGENTS.md +193 -0
  178. package/src/corpus/templates/lms/README.md +27 -0
  179. package/src/corpus/templates/lms/cloudgrid.yaml +237 -0
  180. package/src/corpus/templates/lms/index.md +79 -0
  181. package/src/corpus/templates/marketplace/AGENTS.md +208 -0
  182. package/src/corpus/templates/marketplace/README.md +22 -0
  183. package/src/corpus/templates/marketplace/cloudgrid.yaml +233 -0
  184. package/src/corpus/templates/marketplace/index.md +76 -0
  185. package/src/corpus/templates/membership-site/AGENTS.md +160 -0
  186. package/src/corpus/templates/membership-site/README.md +18 -0
  187. package/src/corpus/templates/membership-site/cloudgrid.yaml +236 -0
  188. package/src/corpus/templates/membership-site/index.md +66 -0
  189. package/src/corpus/templates/monitoring-dashboard/README.md +84 -0
  190. package/src/corpus/templates/monitoring-dashboard/cloudgrid.yaml +233 -0
  191. package/src/corpus/templates/monitoring-dashboard/index.md +328 -0
  192. package/src/corpus/templates/monitoring-dashboard/services/web/app/api/checks/route.js +76 -0
  193. package/src/corpus/templates/monitoring-dashboard/services/web/app/check-form.js +124 -0
  194. package/src/corpus/templates/monitoring-dashboard/services/web/app/layout.js +44 -0
  195. package/src/corpus/templates/monitoring-dashboard/services/web/app/page.js +49 -0
  196. package/src/corpus/templates/monitoring-dashboard/services/web/lib/db.js +32 -0
  197. package/src/corpus/templates/monitoring-dashboard/services/web/package.json +16 -0
  198. package/src/corpus/templates/online-store/AGENTS.md +153 -0
  199. package/src/corpus/templates/online-store/README.md +16 -0
  200. package/src/corpus/templates/online-store/cloudgrid.yaml +234 -0
  201. package/src/corpus/templates/online-store/index.md +81 -0
  202. package/src/corpus/templates/portfolio/cloudgrid.yaml +222 -4
  203. package/src/corpus/templates/portfolio/index.md +3 -5
  204. package/src/corpus/templates/product-catalog/README.md +74 -0
  205. package/src/corpus/templates/product-catalog/cloudgrid.yaml +232 -0
  206. package/src/corpus/templates/product-catalog/index.md +330 -0
  207. package/src/corpus/templates/product-catalog/services/web/app/api/products/route.js +69 -0
  208. package/src/corpus/templates/product-catalog/services/web/app/catalog.js +153 -0
  209. package/src/corpus/templates/product-catalog/services/web/app/layout.js +49 -0
  210. package/src/corpus/templates/product-catalog/services/web/app/page.js +36 -0
  211. package/src/corpus/templates/product-catalog/services/web/lib/db.js +32 -0
  212. package/src/corpus/templates/product-catalog/services/web/package.json +16 -0
  213. package/src/corpus/templates/product-launch/README.md +46 -0
  214. package/src/corpus/templates/product-launch/cloudgrid.yaml +234 -0
  215. package/src/corpus/templates/product-launch/index.html +320 -0
  216. package/src/corpus/templates/product-launch/index.md +34 -0
  217. package/src/corpus/templates/project-management/README.md +83 -0
  218. package/src/corpus/templates/project-management/cloudgrid.yaml +233 -0
  219. package/src/corpus/templates/project-management/index.md +346 -0
  220. package/src/corpus/templates/project-management/services/web/app/api/projects/route.js +48 -0
  221. package/src/corpus/templates/project-management/services/web/app/api/tasks/route.js +85 -0
  222. package/src/corpus/templates/project-management/services/web/app/board.js +182 -0
  223. package/src/corpus/templates/project-management/services/web/app/layout.js +45 -0
  224. package/src/corpus/templates/project-management/services/web/app/page.js +49 -0
  225. package/src/corpus/templates/project-management/services/web/lib/db.js +32 -0
  226. package/src/corpus/templates/project-management/services/web/package.json +16 -0
  227. package/src/corpus/templates/property-listings/README.md +76 -0
  228. package/src/corpus/templates/property-listings/cloudgrid.yaml +233 -0
  229. package/src/corpus/templates/property-listings/index.md +335 -0
  230. package/src/corpus/templates/property-listings/services/web/app/api/properties/route.js +73 -0
  231. package/src/corpus/templates/property-listings/services/web/app/layout.js +45 -0
  232. package/src/corpus/templates/property-listings/services/web/app/listings.js +152 -0
  233. package/src/corpus/templates/property-listings/services/web/app/page.js +53 -0
  234. package/src/corpus/templates/property-listings/services/web/lib/db.js +32 -0
  235. package/src/corpus/templates/property-listings/services/web/package.json +16 -0
  236. package/src/corpus/templates/quiz-platform/README.md +84 -0
  237. package/src/corpus/templates/quiz-platform/cloudgrid.yaml +233 -0
  238. package/src/corpus/templates/quiz-platform/index.md +313 -0
  239. package/src/corpus/templates/quiz-platform/services/web/app/api/questions/route.js +69 -0
  240. package/src/corpus/templates/quiz-platform/services/web/app/layout.js +47 -0
  241. package/src/corpus/templates/quiz-platform/services/web/app/page.js +37 -0
  242. package/src/corpus/templates/quiz-platform/services/web/app/quiz.js +188 -0
  243. package/src/corpus/templates/quiz-platform/services/web/lib/db.js +32 -0
  244. package/src/corpus/templates/quiz-platform/services/web/package.json +16 -0
  245. package/src/corpus/templates/report/cloudgrid.yaml +228 -4
  246. package/src/corpus/templates/report/index.md +3 -5
  247. package/src/corpus/templates/restaurant-reservations/AGENTS.md +258 -0
  248. package/src/corpus/templates/restaurant-reservations/README.md +17 -0
  249. package/src/corpus/templates/restaurant-reservations/cloudgrid.yaml +258 -0
  250. package/src/corpus/templates/restaurant-reservations/index.md +62 -0
  251. package/src/corpus/templates/revenue-dashboard/README.md +75 -0
  252. package/src/corpus/templates/revenue-dashboard/cloudgrid.yaml +233 -0
  253. package/src/corpus/templates/revenue-dashboard/index.md +307 -0
  254. package/src/corpus/templates/revenue-dashboard/services/web/app/api/sales/route.js +60 -0
  255. package/src/corpus/templates/revenue-dashboard/services/web/app/layout.js +40 -0
  256. package/src/corpus/templates/revenue-dashboard/services/web/app/page.js +87 -0
  257. package/src/corpus/templates/revenue-dashboard/services/web/app/sale-form.js +63 -0
  258. package/src/corpus/templates/revenue-dashboard/services/web/lib/db.js +32 -0
  259. package/src/corpus/templates/revenue-dashboard/services/web/package.json +16 -0
  260. package/src/corpus/templates/saas-marketing/cloudgrid.yaml +222 -4
  261. package/src/corpus/templates/saas-marketing/index.md +3 -5
  262. package/src/corpus/templates/semantic-search/AGENTS.md +192 -0
  263. package/src/corpus/templates/semantic-search/README.md +74 -0
  264. package/src/corpus/templates/semantic-search/cloudgrid.yaml +217 -0
  265. package/src/corpus/templates/semantic-search/index.md +97 -0
  266. package/src/corpus/templates/semantic-search/services/backend/requirements.txt +7 -0
  267. package/src/corpus/templates/semantic-search/services/backend/src/app/__init__.py +0 -0
  268. package/src/corpus/templates/semantic-search/services/backend/src/app/answer.py +90 -0
  269. package/src/corpus/templates/semantic-search/services/backend/src/app/auth.py +65 -0
  270. package/src/corpus/templates/semantic-search/services/backend/src/app/config.py +110 -0
  271. package/src/corpus/templates/semantic-search/services/backend/src/app/db.py +89 -0
  272. package/src/corpus/templates/semantic-search/services/backend/src/app/embeddings.py +44 -0
  273. package/src/corpus/templates/semantic-search/services/backend/src/app/indexing.py +222 -0
  274. package/src/corpus/templates/semantic-search/services/backend/src/app/main.py +259 -0
  275. package/src/corpus/templates/semantic-search/services/backend/src/app/search.py +222 -0
  276. package/src/corpus/templates/semantic-search/services/backend/src/app/source.py +259 -0
  277. package/src/corpus/templates/semantic-search/services/backend/src/main.py +12 -0
  278. package/src/corpus/templates/semantic-search/services/web/index.html +12 -0
  279. package/src/corpus/templates/semantic-search/services/web/package-lock.json +1680 -0
  280. package/src/corpus/templates/semantic-search/services/web/package.json +19 -0
  281. package/src/corpus/templates/semantic-search/services/web/src/App.jsx +55 -0
  282. package/src/corpus/templates/semantic-search/services/web/src/api.js +125 -0
  283. package/src/corpus/templates/semantic-search/services/web/src/components/Dashboard.jsx +61 -0
  284. package/src/corpus/templates/semantic-search/services/web/src/components/ManagerLogin.jsx +39 -0
  285. package/src/corpus/templates/semantic-search/services/web/src/components/SearchView.jsx +166 -0
  286. package/src/corpus/templates/semantic-search/services/web/src/components/Settings.jsx +148 -0
  287. package/src/corpus/templates/semantic-search/services/web/src/main.jsx +10 -0
  288. package/src/corpus/templates/semantic-search/services/web/src/styles.css +78 -0
  289. package/src/corpus/templates/semantic-search/services/web/vite.config.js +10 -0
  290. package/src/corpus/templates/status-page/cloudgrid.yaml +222 -4
  291. package/src/corpus/templates/status-page/index.md +3 -5
  292. package/src/corpus/templates/subscription-management/AGENTS.md +191 -0
  293. package/src/corpus/templates/subscription-management/README.md +21 -0
  294. package/src/corpus/templates/subscription-management/cloudgrid.yaml +236 -0
  295. package/src/corpus/templates/subscription-management/index.md +73 -0
  296. package/src/corpus/templates/task-manager/cloudgrid.yaml +226 -8
  297. package/src/corpus/templates/task-manager/index.md +3 -0
  298. package/src/corpus/templates/ticket-system/README.md +71 -0
  299. package/src/corpus/templates/ticket-system/cloudgrid.yaml +233 -0
  300. package/src/corpus/templates/ticket-system/index.md +68 -0
  301. package/src/corpus/templates/ticket-system/services/web/app/api/tickets/route.js +81 -0
  302. package/src/corpus/templates/ticket-system/services/web/app/layout.js +36 -0
  303. package/src/corpus/templates/ticket-system/services/web/app/page.js +35 -0
  304. package/src/corpus/templates/ticket-system/services/web/app/ticket-queue.js +112 -0
  305. package/src/corpus/templates/ticket-system/services/web/lib/db.js +32 -0
  306. package/src/corpus/templates/ticket-system/services/web/package.json +16 -0
  307. package/src/corpus/templates/time-tracking/README.md +81 -0
  308. package/src/corpus/templates/time-tracking/cloudgrid.yaml +233 -0
  309. package/src/corpus/templates/time-tracking/index.md +298 -0
  310. package/src/corpus/templates/time-tracking/services/web/app/api/entries/route.js +66 -0
  311. package/src/corpus/templates/time-tracking/services/web/app/entry-form.js +106 -0
  312. package/src/corpus/templates/time-tracking/services/web/app/layout.js +39 -0
  313. package/src/corpus/templates/time-tracking/services/web/app/page.js +30 -0
  314. package/src/corpus/templates/time-tracking/services/web/lib/db.js +32 -0
  315. package/src/corpus/templates/time-tracking/services/web/package.json +16 -0
  316. package/src/corpus/templates/travel-booking/AGENTS.md +207 -0
  317. package/src/corpus/templates/travel-booking/README.md +17 -0
  318. package/src/corpus/templates/travel-booking/cloudgrid.yaml +249 -0
  319. package/src/corpus/templates/travel-booking/index.md +88 -0
  320. package/src/corpus/templates/waitlist/cloudgrid.yaml +222 -4
  321. package/src/corpus/templates/waitlist/index.md +3 -5
  322. package/src/corpus/templates/web-app/cloudgrid.yaml +228 -4
  323. package/src/corpus/templates/web-app/index.md +3 -5
  324. package/src/corpus/workflows/ai-knowledge-base.md +137 -0
  325. package/src/corpus/workflows/analytics-dashboard.md +104 -0
  326. package/src/corpus/workflows/api-dashboard.md +102 -0
  327. package/src/corpus/workflows/appointment-booking.md +143 -0
  328. package/src/corpus/workflows/approval-workflow.md +124 -0
  329. package/src/corpus/workflows/billing-dashboard.md +120 -0
  330. package/src/corpus/workflows/blog-cms.md +104 -0
  331. package/src/corpus/workflows/booking-system.md +116 -0
  332. package/src/corpus/workflows/calendar-scheduler.md +134 -0
  333. package/src/corpus/workflows/company-website.md +46 -0
  334. package/src/corpus/workflows/course-platform.md +126 -0
  335. package/src/corpus/workflows/directory.md +101 -0
  336. package/src/corpus/workflows/erp.md +125 -0
  337. package/src/corpus/workflows/event-board.md +102 -0
  338. package/src/corpus/workflows/expense-tracker.md +102 -0
  339. package/src/corpus/workflows/feature-request-board.md +105 -0
  340. package/src/corpus/workflows/financial-dashboard.md +103 -0
  341. package/src/corpus/workflows/forum.md +128 -0
  342. package/src/corpus/workflows/hr-portal.md +115 -0
  343. package/src/corpus/workflows/internal-tools-portal.md +125 -0
  344. package/src/corpus/workflows/inventory.md +101 -0
  345. package/src/corpus/workflows/invoice.md +101 -0
  346. package/src/corpus/workflows/job-board.md +101 -0
  347. package/src/corpus/workflows/lms.md +113 -0
  348. package/src/corpus/workflows/marketplace.md +123 -0
  349. package/src/corpus/workflows/membership-site.md +128 -0
  350. package/src/corpus/workflows/monitoring-dashboard.md +104 -0
  351. package/src/corpus/workflows/online-store.md +114 -0
  352. package/src/corpus/workflows/product-catalog.md +105 -0
  353. package/src/corpus/workflows/product-launch.md +43 -0
  354. package/src/corpus/workflows/project-management.md +106 -0
  355. package/src/corpus/workflows/property-listings.md +101 -0
  356. package/src/corpus/workflows/quiz-platform.md +105 -0
  357. package/src/corpus/workflows/restaurant-reservations.md +123 -0
  358. package/src/corpus/workflows/revenue-dashboard.md +102 -0
  359. package/src/corpus/workflows/semantic-search.md +133 -0
  360. package/src/corpus/workflows/subscription-management.md +141 -0
  361. package/src/corpus/workflows/ticket-system.md +101 -0
  362. package/src/corpus/workflows/time-tracking.md +104 -0
  363. package/src/corpus/workflows/travel-booking.md +115 -0
  364. package/src/tools.js +73 -12
@@ -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.
@@ -0,0 +1,235 @@
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: billing-dashboard
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
+ # Stripe secret key for the checkout + webhook + invoice/usage-sync routes. Set
122
+ # the vault item once (`grid secrets set stripe-live-key`); the platform injects
123
+ # it as STRIPE_KEY. Add STRIPE_WEBHOOK_SECRET the same way to verify webhooks.
124
+ vault:
125
+ STRIPE_KEY: stripe-live-key
126
+ # STRIPE_WEBHOOK_SECRET: stripe-webhook-secret
127
+
128
+
129
+ # ─── CONNECTORS AND HOOKS ──────────────────────────────────────────────────
130
+
131
+ # connectors:
132
+ # - id: team-slack
133
+ # target: org # 'system' | 'org'.
134
+ # channel: "#deploys"
135
+ # hooks:
136
+ # - on: deploy.failed # release.published | deploy.failed | feedback.received | entity.created
137
+ # via: team-slack
138
+ # template: "Deploy failed for {entity_name}: {error}"
139
+ # channel: "#alerts"
140
+ # triggers:
141
+ # - from: team-slack
142
+ # event: message
143
+ # channel: "#support"
144
+ # route: /webhooks/slack
145
+
146
+
147
+ # ─── LOCAL DEVELOPMENT ──────────────────────────────────────────────────────
148
+
149
+ # Config for `grid dev`. Redact fields in dev data snapshots.
150
+ # dev:
151
+ # snapshot:
152
+ # mask:
153
+ # - users.email
154
+ # - users.phone
155
+
156
+
157
+ # ─── AGENT METADATA ────────────────────────────────────────────────────────
158
+
159
+ # An agent is an app with kind: agent (above) and an agent: block.
160
+ # agent:
161
+ # purpose: Sync customer data from external CRM every night
162
+ # schedule: "0 2 * * *"
163
+ # trigger: webhook
164
+
165
+
166
+ # ─── PRIVATE RESOURCE AUTO-DEPENDENCIES ────────────────────────────────────
167
+
168
+ # When true (default), private resources are auto-injected as depends_on.
169
+ # auto_depends_on_private_requires: true
170
+
171
+
172
+ # ─── SERVICES (REQUIRED) ───────────────────────────────────────────────────
173
+ #
174
+ # At least one service is required. Key = service name (slug rules).
175
+ # Types: node, nextjs, python, static, cron.
176
+ #
177
+ services:
178
+ web:
179
+ # type (REQUIRED): node | nextjs | python | static | cron
180
+ type: nextjs
181
+ # HTTP route: '/' | '/api' | false (internal) | omitted (=false + warning).
182
+ # Only one service per entity can claim '/'.
183
+ path: /
184
+ # Container port (default 8080; read process.env.PORT). Not for cron.
185
+ # port: 3000
186
+ # nextjs only: base_image: distroless (default) | alpine
187
+ # base_image: distroless
188
+ # node only: lang: javascript (default) | typescript
189
+ # lang: typescript
190
+ # Custom source location (default services/<name>/). '.' = project root.
191
+ # source:
192
+ # path: src/worker
193
+ # Health probe: false/omitted (TCP) | true (/health) | "/path" | {path,expected}
194
+ # health:
195
+ # path: /api/health
196
+ # expected: "200"
197
+ # Static runtime env vars (strings). Reserved: PORT, APP_NAME, SERVICE_NAME,
198
+ # NODE_ENV, MONGODB_URL, REDIS_URL, AI_GATEWAY_URL, N8N_WEBHOOK_URL, CLOUDGRID_*.
199
+ # env:
200
+ # LOG_LEVEL: info
201
+ # Sibling services/private resources that must be Ready first (no cron, no cycles).
202
+ # depends_on:
203
+ # - worker
204
+ # Per-service needs override (merges with app-level needs).
205
+ # needs:
206
+ # queue: true
207
+ # Static-only build step:
208
+ # build:
209
+ # command: npm run build
210
+ # output: dist
211
+ # env:
212
+ # VITE_API_URL: https://api.example.com
213
+ # node_version: "22" # static build step: '18'|'20'|'22'|'24' (quoted)
214
+ # Cron-only: schedule (REQUIRED), timezone (UTC|EST|PST), run (job | https URL)
215
+ # schedule: "0 9 * * 1"
216
+ # timezone: UTC
217
+ # run: job
218
+ # Verbose per-service persistence (prefer needs.disk):
219
+ # persist:
220
+ # - name: scratch
221
+ # path: /tmp/scratch
222
+ # size: 500Mi
223
+
224
+
225
+ needs:
226
+ database: true
227
+
228
+
229
+ # ============================================================================
230
+ # NOTES
231
+ # - NOT here: org:/entity_id: (→ .cloudgrid/link.json), secrets (→ grid secrets set),
232
+ # Dockerfile (platform generates from services.*.type).
233
+ # - Deploy: grid plug | Local with grid resources: grid dev
234
+ # - Full reference: docs/cloudgrid-yaml-reference.md | CLI: docs/cli-reference.md
235
+ # ============================================================================
@@ -0,0 +1,87 @@
1
+ # Template: billing-dashboard (blueprint — Next.js + Mongo + Stripe)
2
+
3
+ A **blueprint** for a real SaaS billing dashboard on CloudGrid: a Next.js app with
4
+ `customers`, `invoices`, `charges`, and `usage_events` in the grid-shared Mongo,
5
+ usage metering, a revenue view (MRR / outstanding / recent invoices), Stripe
6
+ Checkout to collect invoices, and a signature-verified Stripe webhook. This is
7
+ **structure + `cloudgrid.yaml`, not finished app code** — fetch `AGENTS.md` for the
8
+ full build guide, then write the app under `services/web/` and adapt it to the
9
+ user's billing model.
10
+
11
+ **Key rules (same proven shape as `app-with-data`, plus payments):**
12
+
13
+ 1. **App code MUST live under `services/web/`, not the root.** `path: /` in
14
+ `cloudgrid.yaml` is the URL mount, NOT the filesystem path. Files at the root
15
+ fail with `Error: Service directory not found: …/services/web`.
16
+ 2. **Read the Mongo connection string LAZILY (inside a getter), never at module
17
+ top level.** The grid injects it as `DATABASE_MONGODB_URL` (legacy `MONGODB_URL`
18
+ alias) at dev-time and runtime; a top-level read fails `next build`. Never
19
+ hardcode it; never commit a secret.
20
+ 3. **Declare the datastore with `needs: { database: true }`** — the canonical
21
+ shape. `requires:` is the deprecated v1 alias; never set `needs:` and `requires:`
22
+ together (the validator rejects it).
23
+ 4. **The Stripe secret comes from the vault, not code.** The `vault:` block maps the
24
+ vault item `stripe-live-key` → env var `STRIPE_KEY`. Set it with
25
+ `grid secrets set stripe-live-key`; read `process.env.STRIPE_KEY` lazily.
26
+ 5. **Store money as integer cents and trust server-side amounts only.** Compute
27
+ invoice totals server-side; the webhook records the authoritative total from the
28
+ verified Stripe event and reads the RAW request body for signature verification.
29
+
30
+ ## File tree
31
+
32
+ ```
33
+ cloudgrid.yaml # name + services.web (nextjs) + needs:{database:true} + vault:{STRIPE_KEY}
34
+ services/web/package.json # next, react, react-dom, mongodb, stripe
35
+ services/web/lib/db.js # lazy Mongo client (DATABASE_MONGODB_URL / MONGODB_URL)
36
+ services/web/lib/stripe.js # lazy Stripe client (process.env.STRIPE_KEY)
37
+ services/web/lib/money.js # money helpers (integer cents)
38
+ services/web/app/page.js # revenue overview (MRR / outstanding / recent invoices)
39
+ services/web/app/customers/page.js # customers list + [id] detail
40
+ services/web/app/invoices/page.js # invoices list + status filter
41
+ services/web/app/api/customers/route.js # GET/POST customers (mirror to Stripe Customer)
42
+ services/web/app/api/invoices/route.js # GET/POST invoices (draft with line items)
43
+ services/web/app/api/checkout/route.js # POST: Stripe Checkout Session to collect an invoice
44
+ services/web/app/api/usage/route.js # POST: record a metered-usage event
45
+ services/web/app/api/webhook/route.js # POST: verify signature, mark invoices paid, record charges
46
+ ```
47
+
48
+ ## cloudgrid.yaml
49
+
50
+ ```yaml
51
+ # On disk this file is the full-annotated reference (templates/_cloudgrid.yaml.reference) with EVERY
52
+ # field present as a comment; only the fields below are uncommented, so it
53
+ # deploys to exactly these active fields.
54
+ name: billing-dashboard
55
+ vault:
56
+ STRIPE_KEY: stripe-live-key
57
+ services:
58
+ web:
59
+ type: nextjs
60
+ path: /
61
+ needs:
62
+ database: true
63
+ ```
64
+
65
+ > **Capability:** `needs: { database: true }` → the deployer provisions Mongo and
66
+ > injects `DATABASE_MONGODB_URL` (+ legacy `MONGODB_URL`). The `vault:` block maps
67
+ > the org vault item `stripe-live-key` to `STRIPE_KEY` at runtime. See the
68
+ > capability-map for the full injection table.
69
+
70
+ ## Mongo collections
71
+
72
+ - **`customers`** — `name`, `email`, `stripeCustomerId` (`cus_…`), `plan`, `createdAt`.
73
+ - **`invoices`** — `customerId`, `number`, `lineItems[]`, `amountDueCents` (integer
74
+ cents), `currency`, `status` (`draft` → `open` → `paid`/`void`, set to `paid` ONLY
75
+ by the webhook), `stripeSessionId`, `dueDate`, `createdAt`.
76
+ - **`charges`** — `customerId`, `invoiceId`, `amountCents`, `currency`,
77
+ `stripePaymentId` (unique, idempotency), `status` (`succeeded`/`refunded`), `createdAt`.
78
+ - **`usage_events`** — `customerId`, `meter`, `quantity`, `ts` (aggregate per period
79
+ for the revenue view).
80
+
81
+ ## Build it
82
+
83
+ Fetch `gridctl_fetch("template", "billing-dashboard")` and read **`AGENTS.md`** — it
84
+ has the checkout + webhook + usage wiring, the vault/secret setup, and the deploy
85
+ steps (`grid init` → write under `services/web/` → `grid secrets set` → `grid plug`,
86
+ async → poll to a live URL → register the webhook endpoint in Stripe). Adapt the
87
+ collections, fields, and UI to the user's billing model.
@@ -0,0 +1,94 @@
1
+ # blog-cms template — persistent Next.js + Mongo blog / CMS
2
+
3
+ A minimal but real, deployable blog / content site. Posts live in the
4
+ grid-shared MongoDB, so they survive refresh and are shared across
5
+ users/sessions — unlike a static page whose state is in memory only.
6
+
7
+ It is the proven `app-with-data` shape adapted to a `posts` domain: a public
8
+ post list, a single-post page, and an admin screen to create and delete posts.
9
+
10
+ ## Domain
11
+
12
+ A `posts` collection with these fields:
13
+
14
+ | field | type | notes |
15
+ |-------------|-----------|-----------------------------------------|
16
+ | `title` | string | required |
17
+ | `slug` | string | URL key; derived from title if blank |
18
+ | `body` | string | required; post content |
19
+ | `tags` | string[] | optional |
20
+ | `published` | boolean | drafts (`false`) stay off the public list |
21
+ | `createdAt` | Date | set on create |
22
+
23
+ Pages:
24
+
25
+ - `/` — public list of **published** posts (server component).
26
+ - `/posts/[slug]` — a single published post (server component).
27
+ - `/admin` — create / delete posts, drafts included (server list + client form).
28
+
29
+ ## How the grid gives you a database
30
+
31
+ You do **not** provision a database or set a connection string. In
32
+ `cloudgrid.yaml` you declare `needs: { database: true }`, and the grid:
33
+
34
+ - provisions shared Mongo for the app, and
35
+ - injects the connection string as the **`DATABASE_MONGODB_URL`** environment
36
+ variable (plus the legacy `MONGODB_URL` alias) — at dev-time (`grid dev`) and
37
+ at runtime (after `grid plug`).
38
+
39
+ The app reads it via `process.env.DATABASE_MONGODB_URL` (with a legacy
40
+ `process.env.MONGODB_URL` fallback) in `services/web/lib/db.js` — **lazily,
41
+ inside the `getDb` getter, never at module top level** (a top-level read fails
42
+ `next build`, which imports the module for route analysis before the grid injects
43
+ the var). Never hardcode a connection string; never commit a secret.
44
+
45
+ > **Declare `needs: { database: true }` (the canonical shape).** The deployer
46
+ > provisions Mongo and injects `DATABASE_MONGODB_URL` (plus the legacy
47
+ > `MONGODB_URL` alias). `requires:` is the deprecated v1 alias — don't author new
48
+ > yaml with it, and never set `needs:` and `requires:` together (the validator
49
+ > rejects the combination).
50
+
51
+ ## Service layout
52
+
53
+ App code lives under **`services/web/`**, not the template root. `path:` in
54
+ `cloudgrid.yaml` is the URL mount, not the filesystem path — the service named
55
+ `web` means the CLI looks for `services/web/`. Files at the root fail with
56
+ `Error: Service directory not found: …/services/web`.
57
+
58
+ ## Run locally
59
+
60
+ ```bash
61
+ npm install
62
+ grid dev # runs Next.js with DATABASE_MONGODB_URL injected against dev Mongo
63
+ ```
64
+
65
+ ## Deploy
66
+
67
+ ```bash
68
+ grid plug # builds + deploys the folder (async — poll status until live)
69
+ ```
70
+
71
+ A runtime deploy is asynchronous: `plug` returns `status: building`; poll status
72
+ until the app is live, then use the returned live URL. Re-plug the same entity
73
+ to update the same URL.
74
+
75
+ ## File tree
76
+
77
+ ```
78
+ cloudgrid.yaml # name + services.web (nextjs) + needs: { database: true }
79
+ services/web/package.json # next, react, react-dom, mongodb driver only
80
+ services/web/lib/db.js # lazy Mongo client from DATABASE_MONGODB_URL (legacy MONGODB_URL fallback)
81
+ services/web/app/layout.js # root layout + inline CSS
82
+ services/web/app/page.js # server component: public list of published posts
83
+ services/web/app/posts/[slug]/page.js # server component: single published post
84
+ services/web/app/admin/page.js # server component: admin list (drafts + published)
85
+ services/web/app/admin/admin-editor.js # client form: create/delete via the API
86
+ services/web/app/api/posts/route.js # GET (list) / POST (create) / DELETE (remove)
87
+ ```
88
+
89
+ ## Adapt it
90
+
91
+ - Rename the `posts` collection (e.g. `articles`, `pages`, `entries`).
92
+ - Change the document fields (add author, updatedAt, cover image).
93
+ - Add an edit/PATCH route, categories, or pagination as the site grows.
94
+ - Add `cache: true` to `needs:` only if you actually need Redis.