@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,223 @@
1
+ # AGENTS.md — appointment-booking (BLUEPRINT)
2
+
3
+ This is a **blueprint**, not runnable code. It tells an agent how to build an
4
+ appointment / clinic / salon booking app correctly on CloudGrid: a Next.js app
5
+ where a business defines providers and services, publishes bookable time slots,
6
+ and clients book an appointment against an available slot — with auth so a
7
+ provider owns their calendar, optional Stripe deposits, and grid-shared Mongo
8
+ for persistence. Read this whole file, then build the app under `services/web/`
9
+ following the structure below. Do not skip the CloudGrid wiring rules — they are
10
+ what make it deploy.
11
+
12
+ The proven persistent shape is `app-with-data` (Next.js + Mongo). This blueprint
13
+ extends it with auth, availability/slot logic, and optional Stripe deposits.
14
+ Fetch that template for the Mongo lazy-client and App-Router API pattern:
15
+ `gridctl_fetch("template", "app-with-data")`.
16
+
17
+ ## 1. File tree
18
+
19
+ Build exactly this layout. **App code MUST live under `services/web/`** — the
20
+ service is named `web`, so the CLI looks for `services/web/`. `path: /` in
21
+ `cloudgrid.yaml` is the URL mount, NOT the filesystem path. Files at the repo
22
+ root fail with `Error: Service directory not found: …/services/web`.
23
+
24
+ ```
25
+ cloudgrid.yaml # name + services.web (nextjs) + needs:{database:true} + vault: (auth + optional Stripe)
26
+ services/web/package.json # next, react, react-dom, mongodb, + auth SDK (e.g. @clerk/nextjs); stripe only if deposits
27
+ services/web/middleware.js # auth middleware: protects /dashboard/* + provider APIs — anon → sign-in
28
+ services/web/lib/db.js # lazy Mongo client from DATABASE_MONGODB_URL (legacy MONGODB_URL fallback)
29
+ services/web/lib/stripe.js # (optional) lazy Stripe client from process.env.STRIPE_KEY (never top-level)
30
+ services/web/lib/slots.js # availability math: expand a provider's rules into concrete open slots, minus booked
31
+ services/web/app/layout.js # root layout (+ auth provider wrapper if the SDK needs one)
32
+ services/web/app/page.js # public: list providers/services to book
33
+ services/web/app/book/[providerId]/page.js # public: pick a service + an open slot for one provider
34
+ services/web/app/dashboard/layout.js # gate: server-side require signed-in provider; redirect anon → sign-in
35
+ services/web/app/dashboard/page.js # provider view: their services, availability rules, upcoming appointments
36
+ services/web/app/api/providers/route.js # GET list providers (public) / POST create provider (auth: owner)
37
+ services/web/app/api/services/route.js # GET services for a provider / POST create a bookable service (auth)
38
+ services/web/app/api/availability/route.js # GET open slots for provider+date (computed) / POST set availability rules (auth)
39
+ services/web/app/api/appointments/route.js # POST book a slot (public/client) / GET a provider's appointments (auth)
40
+ services/web/app/api/appointments/[id]/route.js# PATCH reschedule/cancel / DELETE (auth or booking token)
41
+ services/web/app/api/checkout/route.js # (optional) POST: Stripe Checkout for a booking deposit → return url
42
+ services/web/app/api/webhook/route.js # (optional) POST: Stripe webhook — mark appointment deposit paid
43
+ services/reminders/ # (INTENDED cron job — PENDING #1543, see §7) reminder sender; not deployable yet
44
+ ```
45
+
46
+ ## 2. Mongo collections + fields
47
+
48
+ The grid provisions Mongo from `needs: { database: true }`. Use four core
49
+ collections. Booking correctness lives here — a slot is bookable only if no
50
+ active `appointments` doc already occupies that provider + start time.
51
+
52
+ **`providers`** — a bookable person/resource (doctor, stylist, room).
53
+ - `_id` (ObjectId)
54
+ - `ownerId` (string, indexed) — the auth provider's user id (Clerk/Auth0 `sub`) that owns this calendar
55
+ - `name` (string), `bio` (string), `timezone` (string, e.g. `"America/New_York"`)
56
+ - `createdAt` (Date)
57
+
58
+ **`services`** — a bookable offering (a "30-min consult", "haircut").
59
+ - `_id` (ObjectId)
60
+ - `providerId` (ObjectId, indexed)
61
+ - `name` (string), `durationMinutes` (number), `priceCents` (number, 0 = free)
62
+ - `depositCents` (number, 0 = no deposit) — drives the optional Stripe flow
63
+ - `active` (boolean)
64
+
65
+ **`availability`** — a provider's recurring open hours (the rules slots expand from).
66
+ - `_id` (ObjectId)
67
+ - `providerId` (ObjectId, indexed)
68
+ - `weekday` (number 0–6) — or store explicit date ranges if you prefer one-off availability
69
+ - `startMinute` (number, minutes past midnight in the provider's tz), `endMinute` (number)
70
+ - `slotMinutes` (number) — granularity to chop the window into
71
+
72
+ **`appointments`** — a booked slot. This is the source of truth for "taken".
73
+ - `_id` (ObjectId)
74
+ - `providerId` (ObjectId, indexed), `serviceId` (ObjectId)
75
+ - `startAt` (Date, UTC, indexed), `endAt` (Date, UTC)
76
+ - `clientName` (string), `clientEmail` (string), `clientPhone` (string)
77
+ - `status` (string) — `"pending" | "confirmed" | "cancelled" | "completed"`
78
+ - `depositStatus` (string) — `"none" | "required" | "paid"` (drives Stripe gating)
79
+ - `stripeSessionId` (string, optional), `reminderSentAt` (Date, optional — the cron sets this)
80
+ - `createdAt` (Date)
81
+
82
+ **Prevent double-booking.** Put a unique index on
83
+ `appointments { providerId, startAt }` for `status ∈ {pending, confirmed}` (a
84
+ partial unique index) and insert the booking inside a guarded write — so two
85
+ clients racing for the same slot cannot both win.
86
+
87
+ ## 3. How CloudGrid injects everything (the wiring that matters)
88
+
89
+ - **Mongo** — declared by `needs: { database: true }`. The deployer provisions
90
+ shared Mongo and injects the connection string as **`DATABASE_MONGODB_URL`**
91
+ (plus the legacy **`MONGODB_URL`** alias) at runtime and under `grid dev`.
92
+ Read `process.env.DATABASE_MONGODB_URL || process.env.MONGODB_URL` **LAZILY,
93
+ inside the getter** in `lib/db.js` — never at module top level, or `next build`
94
+ fails when it imports the module for route analysis before the grid injects
95
+ the var. Never hardcode a connection string. Never set `needs:` and `requires:`
96
+ together — `requires:` is the deprecated v1 alias.
97
+ - **Secrets (auth + optional Stripe) → env vars via the `vault:` block.** In
98
+ `cloudgrid.yaml` the `vault:` block maps each env var to a vault item key:
99
+ ```yaml
100
+ vault:
101
+ AUTH_PROVIDER_KEY: auth-provider-key
102
+ STRIPE_KEY: stripe-live-key # only if you take deposits
103
+ STRIPE_WEBHOOK_SECRET: stripe-webhook-secret # only if you take deposits
104
+ ```
105
+ Set the vault items ONCE with `gridctl_secrets` (or `grid secrets set`), then
106
+ the deployer injects each as the named env var (`process.env.AUTH_PROVIDER_KEY`,
107
+ `process.env.STRIPE_KEY`, …) at runtime and under `grid dev`. Do NOT commit
108
+ keys; do NOT set secrets in `services.web.env` (that block is for non-secret
109
+ config only). Read them LAZILY inside `lib/stripe.js` and the auth setup — same
110
+ rule as the DB.
111
+ - **Public auth keys** — SDKs like Clerk also need a *publishable* key on the
112
+ client (`NEXT_PUBLIC_...`). Publishable keys are not secret; put them in the
113
+ non-secret `services.web.env` block (or as a build-time env), NOT the vault.
114
+ - **AI (optional)** — if you add AI features (e.g. natural-language "book me next
115
+ Tuesday afternoon"), declare `needs: { ai: true }` and call the gateway at
116
+ `process.env.AI_GATEWAY_URL` via `@cloudgrid-io/ai`. Not required for this
117
+ blueprint.
118
+
119
+ ## 4. Wiring auth + payments
120
+
121
+ **Auth (provider SDK, e.g. Clerk or Auth0).** Auth is for the *business side* —
122
+ providers sign in to manage their calendar and see their appointments. Clients
123
+ booking a public slot need not sign in (identify them by `clientEmail`), unless
124
+ you want client accounts.
125
+ 1. Add the SDK to `services/web/package.json` (e.g. `@clerk/nextjs`).
126
+ 2. Server key from the vault (`process.env.AUTH_PROVIDER_KEY`); publishable key
127
+ from `services.web.env` as `NEXT_PUBLIC_...`.
128
+ 3. Wrap the app in the provider in `app/layout.js`.
129
+ 4. `services/web/middleware.js` protects `/dashboard/*` and the write/owner
130
+ endpoints (`POST /api/providers`, `/api/services`, `/api/availability`,
131
+ `GET /api/appointments`). The public booking routes (`GET /api/providers`,
132
+ `GET /api/availability`, `POST /api/appointments`) stay open. Every provider
133
+ API must scope its query by the signed-in `ownerId` — never trust a
134
+ `providerId` from the body for owner actions without checking ownership.
135
+
136
+ **Slot computation (`lib/slots.js`).** This is the heart of correctness:
137
+ 1. For a provider + date, load their `availability` rules for that weekday and
138
+ the provider's `timezone`; chop each open window into `slotMinutes` candidate
139
+ starts, in the provider's local time, converted to UTC.
140
+ 2. Load `appointments` for that provider on that date with
141
+ `status ∈ {pending, confirmed}`; subtract any candidate whose `[startAt,endAt)`
142
+ overlaps a booked one (respect each service's `durationMinutes`).
143
+ 3. Return the remaining open slots. `GET /api/availability` returns these;
144
+ `POST /api/appointments` re-checks availability at write time (never trust the
145
+ client's slot) and inserts under the partial unique index from §2.
146
+
147
+ **Payments (optional Stripe deposit).** Only if a service has `depositCents > 0`.
148
+ 1. Add `stripe` to `package.json`. Build a lazy Stripe client in `lib/stripe.js`
149
+ reading `process.env.STRIPE_KEY` inside the getter.
150
+ 2. **Checkout** — on booking a deposit-required service, `app/api/checkout/route.js`
151
+ (POST) creates a Stripe Checkout Session (`mode: "payment"`, amount =
152
+ `depositCents`), stashes the `appointmentId` in `metadata`, sets `success_url`
153
+ /`cancel_url`, returns `session.url`; the booking is written `status: "pending"`,
154
+ `depositStatus: "required"`, and the client is redirected to pay.
155
+ 3. **Webhook** — `app/api/webhook/route.js` (POST) verifies the signature with
156
+ `process.env.STRIPE_WEBHOOK_SECRET` (read the RAW request body — do not
157
+ JSON-parse before verifying). On `checkout.session.completed`, set the
158
+ appointment `depositStatus: "paid"`, `status: "confirmed"`. Register this
159
+ route's public URL as the webhook endpoint in the Stripe dashboard after
160
+ deploy. If a service has no deposit, book straight to `status: "confirmed"`.
161
+
162
+ ## 5. Deploy steps
163
+
164
+ 1. `gridctl_login_status` → `gridctl_login` if needed. Respect the grid picker
165
+ (ask which grid if the user has more than one).
166
+ 2. `gridctl_init` an app `<name>` FIRST — it creates the entity, writes
167
+ `.cloudgrid/link.json`, and a `cloudgrid.yaml` with empty `services: {}`.
168
+ `plug` needs a linked directory.
169
+ 3. Write the app under `services/web/` and set `cloudgrid.yaml` to the active
170
+ shape: `name` + `services.web{type: nextjs, path: /}` + `needs:{database:true}`
171
+ + the `vault:` block. (Leave the `reminders` cron service COMMENTED — see §7.)
172
+ 4. Set the secrets: `gridctl_secrets` for `auth-provider-key` (and, if taking
173
+ deposits, `stripe-live-key`, `stripe-webhook-secret` — the vault item keys the
174
+ `vault:` block maps from). Non-secret config (auth publishable key, price ids)
175
+ → `gridctl_env` / `services.web.env`. Do NOT set `DATABASE_MONGODB_URL`
176
+ yourself — the grid injects it.
177
+ 5. `gridctl_plug` to deploy. A runtime deploy is **ASYNC** — the first response
178
+ is `status: building`, not a live URL. Poll `gridctl_status` (or the returned
179
+ poll_url) until live; surface a liveness signal while it builds, never a bare
180
+ silent wait.
181
+ 6. If taking deposits, once live add the `/api/webhook` URL as the Stripe webhook
182
+ endpoint, copy the signing secret into the `stripe-webhook-secret` vault item,
183
+ then re-plug. Return the live app URL (not the build/log link).
184
+
185
+ ## 6. Edition note
186
+
187
+ An appointment-booking app is a built + deployed runtime container, so it
188
+ requires the **local edition** (Claude Desktop / Claude Code) or the CLI. The
189
+ **hosted** edition (Claude Web / hosted MCP) is inline-only and can only publish
190
+ static pages — it CANNOT build this app. On hosted, say so plainly and offer a
191
+ static "book us" landing page (via `gridctl_drop`) instead, then stop the runtime
192
+ path.
193
+
194
+ ## 7. Reminders (cron — PENDING platform issue #1543)
195
+
196
+ The design wants a **scheduled reminder job**: on a fixed interval, find
197
+ appointments entering the reminder window (e.g. starting in ~24h) that have not
198
+ had a reminder sent, notify the client (email/SMS via a provider key from the
199
+ vault), and stamp `reminderSentAt` so each appointment is reminded once.
200
+
201
+ The **intended** cron service shape (already present, COMMENTED, in
202
+ `cloudgrid.yaml`):
203
+
204
+ ```yaml
205
+ services:
206
+ reminders:
207
+ type: cron
208
+ schedule: "*/15 * * * *" # every 15 min
209
+ timezone: UTC
210
+ run: job # runs services/reminders/ as a one-shot job per tick
211
+ ```
212
+
213
+ The cron job would live under `services/reminders/` (its own entry that opens the
214
+ same Mongo via the injected `DATABASE_MONGODB_URL`, queries due appointments,
215
+ sends, and stamps `reminderSentAt`). It inherits the app-level `needs: database`
216
+ and can read a notification provider key from the `vault:` block.
217
+
218
+ **IMPORTANT: cron deploy is currently a PENDING platform issue (#1543) and is NOT
219
+ yet deployable.** Keep the `reminders` service COMMENTED in `cloudgrid.yaml` —
220
+ uncommenting it today will not deploy. Until cron ships, either (a) ship the
221
+ booking app without reminders, or (b) trigger reminders manually / from an
222
+ external scheduler hitting an authenticated `/api/appointments` reminder
223
+ endpoint. Document this limitation to the user; do not claim reminders are live.
@@ -0,0 +1,16 @@
1
+ # appointment-booking template — BLUEPRINT (Next.js + auth + Mongo, optional Stripe)
2
+
3
+ An appointment / clinic / salon booking app: a business defines providers and
4
+ bookable services, publishes availability, and clients book an open time slot —
5
+ with auth so a provider owns their calendar, optional Stripe deposits, and
6
+ grid-shared Mongo (`providers`, `services`, `availability`, `appointments`) as
7
+ the source of truth for what is booked. It exists because scheduling is
8
+ correctness-sensitive (no double-booking, availability minus taken slots), so it
9
+ ships as a **blueprint: the structure + the cloudgrid.yaml — adapt and build**,
10
+ not finished code. Read `AGENTS.md` for the file tree, Mongo collections, the
11
+ slot-computation and anti-double-booking rules, and the CloudGrid wiring
12
+ (`needs: { database: true }` → `DATABASE_MONGODB_URL`; auth/Stripe secrets via
13
+ the `vault:` block → env vars), then build the app under `services/web/` and
14
+ deploy (async — poll to a live URL; local edition only). A scheduled reminder
15
+ cron service is designed but its deploy is **PENDING platform issue #1543** — see
16
+ AGENTS.md § 7.
@@ -0,0 +1,250 @@
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: appointment-booking
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
+ # Auth (so providers/clients own bookings) and optional deposit payments need
122
+ # secrets injected as env vars — this is the CloudGrid-correct way. Set each
123
+ # vault item once (grid secrets set), then the deployer injects it as the named
124
+ # env var at runtime and under `grid dev`. Read them LAZILY, never top-level.
125
+ vault:
126
+ AUTH_PROVIDER_KEY: auth-provider-key # auth SDK server key (e.g. Clerk secret / Auth0 client secret)
127
+ STRIPE_KEY: stripe-live-key # Stripe secret key — optional booking deposits / prepayment
128
+ STRIPE_WEBHOOK_SECRET: stripe-webhook-secret # verifies Stripe webhook signatures (deposit confirmation)
129
+
130
+
131
+ # ─── CONNECTORS AND HOOKS ──────────────────────────────────────────────────
132
+
133
+ # connectors:
134
+ # - id: team-slack
135
+ # target: org # 'system' | 'org'.
136
+ # channel: "#deploys"
137
+ # hooks:
138
+ # - on: deploy.failed # release.published | deploy.failed | feedback.received | entity.created
139
+ # via: team-slack
140
+ # template: "Deploy failed for {entity_name}: {error}"
141
+ # channel: "#alerts"
142
+ # triggers:
143
+ # - from: team-slack
144
+ # event: message
145
+ # channel: "#support"
146
+ # route: /webhooks/slack
147
+
148
+
149
+ # ─── LOCAL DEVELOPMENT ──────────────────────────────────────────────────────
150
+
151
+ # Config for `grid dev`. Redact fields in dev data snapshots.
152
+ # dev:
153
+ # snapshot:
154
+ # mask:
155
+ # - users.email
156
+ # - users.phone
157
+
158
+
159
+ # ─── AGENT METADATA ────────────────────────────────────────────────────────
160
+
161
+ # An agent is an app with kind: agent (above) and an agent: block.
162
+ # agent:
163
+ # purpose: Sync customer data from external CRM every night
164
+ # schedule: "0 2 * * *"
165
+ # trigger: webhook
166
+
167
+
168
+ # ─── PRIVATE RESOURCE AUTO-DEPENDENCIES ────────────────────────────────────
169
+
170
+ # When true (default), private resources are auto-injected as depends_on.
171
+ # auto_depends_on_private_requires: true
172
+
173
+
174
+ # ─── SERVICES (REQUIRED) ───────────────────────────────────────────────────
175
+ #
176
+ # At least one service is required. Key = service name (slug rules).
177
+ # Types: node, nextjs, python, static, cron.
178
+ #
179
+ services:
180
+ web:
181
+ # type (REQUIRED): node | nextjs | python | static | cron
182
+ type: nextjs
183
+ # HTTP route: '/' | '/api' | false (internal) | omitted (=false + warning).
184
+ # Only one service per entity can claim '/'.
185
+ path: /
186
+ # Container port (default 8080; read process.env.PORT). Not for cron.
187
+ # port: 3000
188
+ # nextjs only: base_image: distroless (default) | alpine
189
+ # base_image: distroless
190
+ # node only: lang: javascript (default) | typescript
191
+ # lang: typescript
192
+ # Custom source location (default services/<name>/). '.' = project root.
193
+ # source:
194
+ # path: src/worker
195
+ # Health probe: false/omitted (TCP) | true (/health) | "/path" | {path,expected}
196
+ # health:
197
+ # path: /api/health
198
+ # expected: "200"
199
+ # Static runtime env vars (strings). Reserved: PORT, APP_NAME, SERVICE_NAME,
200
+ # NODE_ENV, MONGODB_URL, REDIS_URL, AI_GATEWAY_URL, N8N_WEBHOOK_URL, CLOUDGRID_*.
201
+ # env:
202
+ # LOG_LEVEL: info
203
+ # Sibling services/private resources that must be Ready first (no cron, no cycles).
204
+ # depends_on:
205
+ # - worker
206
+ # Per-service needs override (merges with app-level needs).
207
+ # needs:
208
+ # queue: true
209
+ # Static-only build step:
210
+ # build:
211
+ # command: npm run build
212
+ # output: dist
213
+ # env:
214
+ # VITE_API_URL: https://api.example.com
215
+ # node_version: "22" # static build step: '18'|'20'|'22'|'24' (quoted)
216
+ # Cron-only: schedule (REQUIRED), timezone (UTC|EST|PST), run (job | https URL)
217
+ # schedule: "0 9 * * 1"
218
+ # timezone: UTC
219
+ # run: job
220
+ # Verbose per-service persistence (prefer needs.disk):
221
+ # persist:
222
+ # - name: scratch
223
+ # path: /tmp/scratch
224
+ # size: 500Mi
225
+
226
+ # ── INTENDED cron service — appointment reminders (NOT YET DEPLOYABLE) ──
227
+ # This design wants a scheduled job to send reminders for upcoming
228
+ # appointments (e.g. "24h before"). The shape below is the intended cron
229
+ # service. Cron deploy is a PENDING platform issue (#1543) — leave this
230
+ # COMMENTED until cron ships; uncommenting it today will not deploy. See
231
+ # AGENTS.md § "Reminders (cron — PENDING #1543)" for the intended behaviour.
232
+ # reminders:
233
+ # type: cron
234
+ # schedule: "*/15 * * * *" # every 15 min: find appts entering the reminder window
235
+ # timezone: UTC
236
+ # run: job # runs services/reminders/ as a one-shot job per tick
237
+ # # Inherits app-level needs (database) + vault (for the notification provider key).
238
+
239
+
240
+ needs:
241
+ database: true
242
+
243
+
244
+ # ============================================================================
245
+ # NOTES
246
+ # - NOT here: org:/entity_id: (→ .cloudgrid/link.json), secrets (→ grid secrets set),
247
+ # Dockerfile (platform generates from services.*.type).
248
+ # - Deploy: grid plug | Local with grid resources: grid dev
249
+ # - Full reference: docs/cloudgrid-yaml-reference.md | CLI: docs/cli-reference.md
250
+ # ============================================================================
@@ -0,0 +1,72 @@
1
+ # Template: appointment-booking (BLUEPRINT — Next.js + auth + Mongo, optional Stripe)
2
+
3
+ An appointment / clinic / salon booking app. **Blueprint, not finished code**:
4
+ it ships the `cloudgrid.yaml` and a structure guide (`AGENTS.md`) so an agent can
5
+ build it correctly on CloudGrid — a Next.js app where a business defines
6
+ providers and bookable services, publishes availability, and clients book an open
7
+ slot, with auth so a provider owns their calendar, optional Stripe deposits, and
8
+ grid-shared Mongo. Read `AGENTS.md`, build the app under `services/web/`, adapt
9
+ the providers/services/slot rules, then deploy (async — poll to a live URL).
10
+ Local edition only.
11
+
12
+ **Fetch the bundle:**
13
+ - `gridctl_fetch("template", "appointment-booking")` — this blueprint (`cloudgrid.yaml` + `AGENTS.md`).
14
+ - `gridctl_fetch("template", "app-with-data")` — the proven Next.js + Mongo shape to extend (lazy db client, App-Router API).
15
+
16
+ **Key rules:**
17
+
18
+ 1. **Blueprint — read `AGENTS.md` first.** It has the file tree, the Mongo
19
+ collections (`providers`, `services`, `availability`, `appointments`), the
20
+ slot-computation + anti-double-booking rules, the CloudGrid injection table,
21
+ and the auth + Stripe wiring. Build following it; do not invent structure.
22
+ 2. **App code MUST live under `services/web/`.** `path: /` is the URL mount, NOT
23
+ the filesystem path. Root files fail with `Service directory not found`.
24
+ 3. **Mongo via `needs:{database:true}`** → the grid injects
25
+ `DATABASE_MONGODB_URL` (legacy `MONGODB_URL` fallback). Read it LAZILY inside
26
+ the getter, never at module top level (top-level read fails `next build`).
27
+ 4. **Secrets via the `vault:` block** → env vars. `AUTH_PROVIDER_KEY` (and, for
28
+ deposits, `STRIPE_KEY` / `STRIPE_WEBHOOK_SECRET`) map to vault items; set them
29
+ with `gridctl_secrets`, and the deployer injects them at runtime. Read lazily;
30
+ do not commit keys or put secrets in `services.web.env`.
31
+ 5. **No double-booking.** `appointments` is the source of truth for "taken";
32
+ compute open slots as availability minus booked, re-check at write time, and
33
+ guard the insert with a partial unique index on `{ providerId, startAt }`.
34
+ 6. **Never set `needs:` and `requires:` together** — `requires:` is the
35
+ deprecated v1 alias.
36
+ 7. **Reminders (cron) are designed but PENDING platform issue #1543** — keep the
37
+ `reminders` cron service COMMENTED in `cloudgrid.yaml`; it is not yet
38
+ deployable. See AGENTS.md § 7.
39
+
40
+ ## cloudgrid.yaml (active fields)
41
+
42
+ ```yaml
43
+ # On disk this file is the full-annotated reference (templates/_cloudgrid.yaml.reference) with EVERY
44
+ # field present as a comment; only the fields below are uncommented, so it
45
+ # deploys to exactly these active fields.
46
+ name: appointment-booking
47
+ services:
48
+ web:
49
+ type: nextjs
50
+ path: /
51
+ needs:
52
+ database: true
53
+ vault:
54
+ AUTH_PROVIDER_KEY: auth-provider-key
55
+ STRIPE_KEY: stripe-live-key
56
+ STRIPE_WEBHOOK_SECRET: stripe-webhook-secret
57
+ ```
58
+
59
+ > **Capability:** `needs: { database: true }` → the deployer provisions Mongo and
60
+ > injects `DATABASE_MONGODB_URL` (+ legacy `MONGODB_URL`). The `vault:` block maps
61
+ > auth/Stripe secrets to env vars — the CloudGrid-correct way to inject
62
+ > credentials. `requires:` is the deprecated v1 alias; don't mix it with `needs:`.
63
+ > A `reminders` cron service is designed (commented) but cron deploy is PENDING
64
+ > #1543. See the capability-map for the full injection table.
65
+
66
+ ## Deploy (async, local edition)
67
+
68
+ `gridctl_init` first (creates the entity + link.json), write the app under
69
+ `services/web/`, set the vault secrets with `gridctl_secrets`, `gridctl_plug`
70
+ (async — poll `gridctl_status` to a live URL). If taking deposits, register the
71
+ `/api/webhook` URL in Stripe and re-plug. Re-plug the same entity to update the
72
+ same URL.