@cloudgrid-io/mcp 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (390) hide show
  1. package/package.json +1 -1
  2. package/src/corpus/capability-map.md +82 -2
  3. package/src/corpus/examples/crm/index.md +273 -0
  4. package/src/corpus/examples/kanban/index.md +256 -0
  5. package/src/corpus/templates/_cloudgrid.yaml.reference +228 -0
  6. package/src/corpus/templates/admin-dashboard/README.md +75 -0
  7. package/src/corpus/templates/admin-dashboard/cloudgrid.yaml +233 -0
  8. package/src/corpus/templates/admin-dashboard/index.md +81 -0
  9. package/src/corpus/templates/admin-dashboard/services/web/app/api/orders/route.js +64 -0
  10. package/src/corpus/templates/admin-dashboard/services/web/app/api/users/route.js +63 -0
  11. package/src/corpus/templates/admin-dashboard/services/web/app/layout.js +39 -0
  12. package/src/corpus/templates/admin-dashboard/services/web/app/page.js +73 -0
  13. package/src/corpus/templates/admin-dashboard/services/web/app/resource-table.js +94 -0
  14. package/src/corpus/templates/admin-dashboard/services/web/lib/db.js +32 -0
  15. package/src/corpus/templates/admin-dashboard/services/web/package.json +16 -0
  16. package/src/corpus/templates/ai-app/cloudgrid.yaml +225 -11
  17. package/src/corpus/templates/ai-app/index.md +3 -11
  18. package/src/corpus/templates/ai-knowledge-base/AGENTS.md +254 -0
  19. package/src/corpus/templates/ai-knowledge-base/README.md +28 -0
  20. package/src/corpus/templates/ai-knowledge-base/cloudgrid.yaml +238 -0
  21. package/src/corpus/templates/ai-knowledge-base/index.md +81 -0
  22. package/src/corpus/templates/analytics-dashboard/README.md +85 -0
  23. package/src/corpus/templates/analytics-dashboard/cloudgrid.yaml +232 -0
  24. package/src/corpus/templates/analytics-dashboard/index.md +316 -0
  25. package/src/corpus/templates/analytics-dashboard/services/web/app/api/events/route.js +60 -0
  26. package/src/corpus/templates/analytics-dashboard/services/web/app/event-form.js +100 -0
  27. package/src/corpus/templates/analytics-dashboard/services/web/app/layout.js +41 -0
  28. package/src/corpus/templates/analytics-dashboard/services/web/app/page.js +54 -0
  29. package/src/corpus/templates/analytics-dashboard/services/web/lib/db.js +32 -0
  30. package/src/corpus/templates/analytics-dashboard/services/web/package.json +16 -0
  31. package/src/corpus/templates/api-dashboard/README.md +84 -0
  32. package/src/corpus/templates/api-dashboard/cloudgrid.yaml +233 -0
  33. package/src/corpus/templates/api-dashboard/index.md +310 -0
  34. package/src/corpus/templates/api-dashboard/services/web/app/api/requests/route.js +62 -0
  35. package/src/corpus/templates/api-dashboard/services/web/app/dashboard.js +156 -0
  36. package/src/corpus/templates/api-dashboard/services/web/app/layout.js +42 -0
  37. package/src/corpus/templates/api-dashboard/services/web/app/page.js +39 -0
  38. package/src/corpus/templates/api-dashboard/services/web/lib/db.js +32 -0
  39. package/src/corpus/templates/api-dashboard/services/web/package.json +16 -0
  40. package/src/corpus/templates/api-docs/README.md +28 -0
  41. package/src/corpus/templates/api-docs/cloudgrid.yaml +228 -0
  42. package/src/corpus/templates/api-docs/index.html +136 -0
  43. package/src/corpus/templates/api-docs/index.md +28 -0
  44. package/src/corpus/templates/api-service/cloudgrid.yaml +224 -9
  45. package/src/corpus/templates/api-service/index.md +3 -11
  46. package/src/corpus/templates/app-with-data/cloudgrid.yaml +226 -8
  47. package/src/corpus/templates/app-with-data/index.md +3 -8
  48. package/src/corpus/templates/appointment-booking/AGENTS.md +223 -0
  49. package/src/corpus/templates/appointment-booking/README.md +16 -0
  50. package/src/corpus/templates/appointment-booking/cloudgrid.yaml +250 -0
  51. package/src/corpus/templates/appointment-booking/index.md +72 -0
  52. package/src/corpus/templates/approval-workflow/AGENTS.md +170 -0
  53. package/src/corpus/templates/approval-workflow/README.md +12 -0
  54. package/src/corpus/templates/approval-workflow/cloudgrid.yaml +237 -0
  55. package/src/corpus/templates/approval-workflow/index.md +58 -0
  56. package/src/corpus/templates/billing-dashboard/AGENTS.md +199 -0
  57. package/src/corpus/templates/billing-dashboard/README.md +18 -0
  58. package/src/corpus/templates/billing-dashboard/cloudgrid.yaml +235 -0
  59. package/src/corpus/templates/billing-dashboard/index.md +87 -0
  60. package/src/corpus/templates/blog-cms/README.md +94 -0
  61. package/src/corpus/templates/blog-cms/cloudgrid.yaml +233 -0
  62. package/src/corpus/templates/blog-cms/index.md +358 -0
  63. package/src/corpus/templates/blog-cms/services/web/app/admin/admin-editor.js +133 -0
  64. package/src/corpus/templates/blog-cms/services/web/app/admin/page.js +33 -0
  65. package/src/corpus/templates/blog-cms/services/web/app/api/posts/route.js +84 -0
  66. package/src/corpus/templates/blog-cms/services/web/app/layout.js +47 -0
  67. package/src/corpus/templates/blog-cms/services/web/app/page.js +56 -0
  68. package/src/corpus/templates/blog-cms/services/web/app/posts/[slug]/page.js +45 -0
  69. package/src/corpus/templates/blog-cms/services/web/lib/db.js +32 -0
  70. package/src/corpus/templates/blog-cms/services/web/package.json +16 -0
  71. package/src/corpus/templates/booking-system/AGENTS.md +189 -0
  72. package/src/corpus/templates/booking-system/README.md +17 -0
  73. package/src/corpus/templates/booking-system/cloudgrid.yaml +248 -0
  74. package/src/corpus/templates/booking-system/index.md +86 -0
  75. package/src/corpus/templates/calendar-scheduler/AGENTS.md +226 -0
  76. package/src/corpus/templates/calendar-scheduler/README.md +25 -0
  77. package/src/corpus/templates/calendar-scheduler/cloudgrid.yaml +259 -0
  78. package/src/corpus/templates/calendar-scheduler/index.md +85 -0
  79. package/src/corpus/templates/changelog/README.md +27 -0
  80. package/src/corpus/templates/changelog/cloudgrid.yaml +228 -0
  81. package/src/corpus/templates/changelog/index.html +80 -0
  82. package/src/corpus/templates/changelog/index.md +28 -0
  83. package/src/corpus/templates/company-website/README.md +54 -0
  84. package/src/corpus/templates/company-website/cloudgrid.yaml +233 -0
  85. package/src/corpus/templates/company-website/index.html +309 -0
  86. package/src/corpus/templates/company-website/index.md +29 -0
  87. package/src/corpus/templates/course-platform/AGENTS.md +161 -0
  88. package/src/corpus/templates/course-platform/README.md +26 -0
  89. package/src/corpus/templates/course-platform/cloudgrid.yaml +237 -0
  90. package/src/corpus/templates/course-platform/index.md +70 -0
  91. package/src/corpus/templates/crm/README.md +72 -0
  92. package/src/corpus/templates/crm/cloudgrid.yaml +233 -0
  93. package/src/corpus/templates/crm/index.md +71 -0
  94. package/src/corpus/templates/crm/services/web/app/api/contacts/route.js +80 -0
  95. package/src/corpus/templates/crm/services/web/app/contact-manager.js +102 -0
  96. package/src/corpus/templates/crm/services/web/app/layout.js +35 -0
  97. package/src/corpus/templates/crm/services/web/app/page.js +34 -0
  98. package/src/corpus/templates/crm/services/web/lib/db.js +32 -0
  99. package/src/corpus/templates/crm/services/web/package.json +16 -0
  100. package/src/corpus/templates/dashboard/cloudgrid.yaml +228 -4
  101. package/src/corpus/templates/dashboard/index.md +3 -5
  102. package/src/corpus/templates/deck/cloudgrid.yaml +228 -4
  103. package/src/corpus/templates/deck/index.md +3 -5
  104. package/src/corpus/templates/directory/README.md +75 -0
  105. package/src/corpus/templates/directory/cloudgrid.yaml +233 -0
  106. package/src/corpus/templates/directory/index.md +334 -0
  107. package/src/corpus/templates/directory/services/web/app/api/entries/route.js +63 -0
  108. package/src/corpus/templates/directory/services/web/app/directory-list.js +146 -0
  109. package/src/corpus/templates/directory/services/web/app/layout.js +44 -0
  110. package/src/corpus/templates/directory/services/web/app/page.js +38 -0
  111. package/src/corpus/templates/directory/services/web/lib/db.js +32 -0
  112. package/src/corpus/templates/directory/services/web/package.json +16 -0
  113. package/src/corpus/templates/docs-site/README.md +28 -0
  114. package/src/corpus/templates/docs-site/cloudgrid.yaml +228 -0
  115. package/src/corpus/templates/docs-site/index.html +122 -0
  116. package/src/corpus/templates/docs-site/index.md +28 -0
  117. package/src/corpus/templates/erp/AGENTS.md +116 -0
  118. package/src/corpus/templates/erp/README.md +17 -0
  119. package/src/corpus/templates/erp/cloudgrid.yaml +235 -0
  120. package/src/corpus/templates/erp/index.md +81 -0
  121. package/src/corpus/templates/event-board/README.md +74 -0
  122. package/src/corpus/templates/event-board/cloudgrid.yaml +233 -0
  123. package/src/corpus/templates/event-board/index.md +299 -0
  124. package/src/corpus/templates/event-board/services/web/app/api/events/route.js +61 -0
  125. package/src/corpus/templates/event-board/services/web/app/event-form.js +118 -0
  126. package/src/corpus/templates/event-board/services/web/app/layout.js +39 -0
  127. package/src/corpus/templates/event-board/services/web/app/page.js +34 -0
  128. package/src/corpus/templates/event-board/services/web/lib/db.js +32 -0
  129. package/src/corpus/templates/event-board/services/web/package.json +16 -0
  130. package/src/corpus/templates/expense-tracker/README.md +76 -0
  131. package/src/corpus/templates/expense-tracker/cloudgrid.yaml +233 -0
  132. package/src/corpus/templates/expense-tracker/index.md +305 -0
  133. package/src/corpus/templates/expense-tracker/services/web/app/api/expenses/route.js +61 -0
  134. package/src/corpus/templates/expense-tracker/services/web/app/expense-form.js +145 -0
  135. package/src/corpus/templates/expense-tracker/services/web/app/layout.js +42 -0
  136. package/src/corpus/templates/expense-tracker/services/web/app/page.js +34 -0
  137. package/src/corpus/templates/expense-tracker/services/web/lib/db.js +32 -0
  138. package/src/corpus/templates/expense-tracker/services/web/package.json +16 -0
  139. package/src/corpus/templates/feature-request-board/README.md +87 -0
  140. package/src/corpus/templates/feature-request-board/cloudgrid.yaml +233 -0
  141. package/src/corpus/templates/feature-request-board/index.md +317 -0
  142. package/src/corpus/templates/feature-request-board/services/web/app/api/requests/route.js +92 -0
  143. package/src/corpus/templates/feature-request-board/services/web/app/board.js +91 -0
  144. package/src/corpus/templates/feature-request-board/services/web/app/layout.js +43 -0
  145. package/src/corpus/templates/feature-request-board/services/web/app/page.js +35 -0
  146. package/src/corpus/templates/feature-request-board/services/web/lib/db.js +32 -0
  147. package/src/corpus/templates/feature-request-board/services/web/package.json +16 -0
  148. package/src/corpus/templates/financial-dashboard/README.md +80 -0
  149. package/src/corpus/templates/financial-dashboard/cloudgrid.yaml +233 -0
  150. package/src/corpus/templates/financial-dashboard/index.md +326 -0
  151. package/src/corpus/templates/financial-dashboard/services/web/app/api/entries/route.js +63 -0
  152. package/src/corpus/templates/financial-dashboard/services/web/app/entry-board.js +130 -0
  153. package/src/corpus/templates/financial-dashboard/services/web/app/layout.js +46 -0
  154. package/src/corpus/templates/financial-dashboard/services/web/app/page.js +31 -0
  155. package/src/corpus/templates/financial-dashboard/services/web/lib/db.js +32 -0
  156. package/src/corpus/templates/financial-dashboard/services/web/package.json +16 -0
  157. package/src/corpus/templates/forum/AGENTS.md +196 -0
  158. package/src/corpus/templates/forum/README.md +12 -0
  159. package/src/corpus/templates/forum/cloudgrid.yaml +237 -0
  160. package/src/corpus/templates/forum/index.md +66 -0
  161. package/src/corpus/templates/hr-portal/AGENTS.md +174 -0
  162. package/src/corpus/templates/hr-portal/README.md +14 -0
  163. package/src/corpus/templates/hr-portal/cloudgrid.yaml +237 -0
  164. package/src/corpus/templates/hr-portal/index.md +56 -0
  165. package/src/corpus/templates/internal-tools-portal/AGENTS.md +201 -0
  166. package/src/corpus/templates/internal-tools-portal/README.md +17 -0
  167. package/src/corpus/templates/internal-tools-portal/cloudgrid.yaml +237 -0
  168. package/src/corpus/templates/internal-tools-portal/index.md +62 -0
  169. package/src/corpus/templates/inventory/README.md +71 -0
  170. package/src/corpus/templates/inventory/cloudgrid.yaml +233 -0
  171. package/src/corpus/templates/inventory/index.md +68 -0
  172. package/src/corpus/templates/inventory/services/web/app/api/items/route.js +88 -0
  173. package/src/corpus/templates/inventory/services/web/app/inventory-manager.js +101 -0
  174. package/src/corpus/templates/inventory/services/web/app/layout.js +36 -0
  175. package/src/corpus/templates/inventory/services/web/app/page.js +37 -0
  176. package/src/corpus/templates/inventory/services/web/lib/db.js +32 -0
  177. package/src/corpus/templates/inventory/services/web/package.json +16 -0
  178. package/src/corpus/templates/invoice/README.md +71 -0
  179. package/src/corpus/templates/invoice/cloudgrid.yaml +233 -0
  180. package/src/corpus/templates/invoice/index.md +68 -0
  181. package/src/corpus/templates/invoice/services/web/app/api/invoices/route.js +82 -0
  182. package/src/corpus/templates/invoice/services/web/app/invoice-manager.js +101 -0
  183. package/src/corpus/templates/invoice/services/web/app/layout.js +35 -0
  184. package/src/corpus/templates/invoice/services/web/app/page.js +34 -0
  185. package/src/corpus/templates/invoice/services/web/lib/db.js +32 -0
  186. package/src/corpus/templates/invoice/services/web/package.json +16 -0
  187. package/src/corpus/templates/job-board/README.md +71 -0
  188. package/src/corpus/templates/job-board/cloudgrid.yaml +233 -0
  189. package/src/corpus/templates/job-board/index.md +68 -0
  190. package/src/corpus/templates/job-board/services/web/app/api/jobs/route.js +66 -0
  191. package/src/corpus/templates/job-board/services/web/app/job-board.js +73 -0
  192. package/src/corpus/templates/job-board/services/web/app/layout.js +35 -0
  193. package/src/corpus/templates/job-board/services/web/app/page.js +32 -0
  194. package/src/corpus/templates/job-board/services/web/lib/db.js +32 -0
  195. package/src/corpus/templates/job-board/services/web/package.json +16 -0
  196. package/src/corpus/templates/kanban/README.md +72 -0
  197. package/src/corpus/templates/kanban/cloudgrid.yaml +233 -0
  198. package/src/corpus/templates/kanban/index.md +71 -0
  199. package/src/corpus/templates/kanban/services/web/app/api/cards/route.js +70 -0
  200. package/src/corpus/templates/kanban/services/web/app/board.js +93 -0
  201. package/src/corpus/templates/kanban/services/web/app/layout.js +37 -0
  202. package/src/corpus/templates/kanban/services/web/app/page.js +32 -0
  203. package/src/corpus/templates/kanban/services/web/lib/db.js +32 -0
  204. package/src/corpus/templates/kanban/services/web/package.json +16 -0
  205. package/src/corpus/templates/landing-page/cloudgrid.yaml +228 -4
  206. package/src/corpus/templates/landing-page/index.md +3 -5
  207. package/src/corpus/templates/lms/AGENTS.md +193 -0
  208. package/src/corpus/templates/lms/README.md +27 -0
  209. package/src/corpus/templates/lms/cloudgrid.yaml +237 -0
  210. package/src/corpus/templates/lms/index.md +79 -0
  211. package/src/corpus/templates/marketplace/AGENTS.md +208 -0
  212. package/src/corpus/templates/marketplace/README.md +22 -0
  213. package/src/corpus/templates/marketplace/cloudgrid.yaml +233 -0
  214. package/src/corpus/templates/marketplace/index.md +76 -0
  215. package/src/corpus/templates/membership-site/AGENTS.md +160 -0
  216. package/src/corpus/templates/membership-site/README.md +18 -0
  217. package/src/corpus/templates/membership-site/cloudgrid.yaml +236 -0
  218. package/src/corpus/templates/membership-site/index.md +66 -0
  219. package/src/corpus/templates/monitoring-dashboard/README.md +84 -0
  220. package/src/corpus/templates/monitoring-dashboard/cloudgrid.yaml +233 -0
  221. package/src/corpus/templates/monitoring-dashboard/index.md +328 -0
  222. package/src/corpus/templates/monitoring-dashboard/services/web/app/api/checks/route.js +76 -0
  223. package/src/corpus/templates/monitoring-dashboard/services/web/app/check-form.js +124 -0
  224. package/src/corpus/templates/monitoring-dashboard/services/web/app/layout.js +44 -0
  225. package/src/corpus/templates/monitoring-dashboard/services/web/app/page.js +49 -0
  226. package/src/corpus/templates/monitoring-dashboard/services/web/lib/db.js +32 -0
  227. package/src/corpus/templates/monitoring-dashboard/services/web/package.json +16 -0
  228. package/src/corpus/templates/online-store/AGENTS.md +153 -0
  229. package/src/corpus/templates/online-store/README.md +16 -0
  230. package/src/corpus/templates/online-store/cloudgrid.yaml +234 -0
  231. package/src/corpus/templates/online-store/index.md +81 -0
  232. package/src/corpus/templates/portfolio/README.md +29 -0
  233. package/src/corpus/templates/portfolio/cloudgrid.yaml +228 -0
  234. package/src/corpus/templates/portfolio/index.html +126 -0
  235. package/src/corpus/templates/portfolio/index.md +28 -0
  236. package/src/corpus/templates/product-catalog/README.md +74 -0
  237. package/src/corpus/templates/product-catalog/cloudgrid.yaml +232 -0
  238. package/src/corpus/templates/product-catalog/index.md +330 -0
  239. package/src/corpus/templates/product-catalog/services/web/app/api/products/route.js +69 -0
  240. package/src/corpus/templates/product-catalog/services/web/app/catalog.js +153 -0
  241. package/src/corpus/templates/product-catalog/services/web/app/layout.js +49 -0
  242. package/src/corpus/templates/product-catalog/services/web/app/page.js +36 -0
  243. package/src/corpus/templates/product-catalog/services/web/lib/db.js +32 -0
  244. package/src/corpus/templates/product-catalog/services/web/package.json +16 -0
  245. package/src/corpus/templates/product-launch/README.md +46 -0
  246. package/src/corpus/templates/product-launch/cloudgrid.yaml +234 -0
  247. package/src/corpus/templates/product-launch/index.html +320 -0
  248. package/src/corpus/templates/product-launch/index.md +34 -0
  249. package/src/corpus/templates/project-management/README.md +83 -0
  250. package/src/corpus/templates/project-management/cloudgrid.yaml +233 -0
  251. package/src/corpus/templates/project-management/index.md +346 -0
  252. package/src/corpus/templates/project-management/services/web/app/api/projects/route.js +48 -0
  253. package/src/corpus/templates/project-management/services/web/app/api/tasks/route.js +85 -0
  254. package/src/corpus/templates/project-management/services/web/app/board.js +182 -0
  255. package/src/corpus/templates/project-management/services/web/app/layout.js +45 -0
  256. package/src/corpus/templates/project-management/services/web/app/page.js +49 -0
  257. package/src/corpus/templates/project-management/services/web/lib/db.js +32 -0
  258. package/src/corpus/templates/project-management/services/web/package.json +16 -0
  259. package/src/corpus/templates/property-listings/README.md +76 -0
  260. package/src/corpus/templates/property-listings/cloudgrid.yaml +233 -0
  261. package/src/corpus/templates/property-listings/index.md +335 -0
  262. package/src/corpus/templates/property-listings/services/web/app/api/properties/route.js +73 -0
  263. package/src/corpus/templates/property-listings/services/web/app/layout.js +45 -0
  264. package/src/corpus/templates/property-listings/services/web/app/listings.js +152 -0
  265. package/src/corpus/templates/property-listings/services/web/app/page.js +53 -0
  266. package/src/corpus/templates/property-listings/services/web/lib/db.js +32 -0
  267. package/src/corpus/templates/property-listings/services/web/package.json +16 -0
  268. package/src/corpus/templates/quiz-platform/README.md +84 -0
  269. package/src/corpus/templates/quiz-platform/cloudgrid.yaml +233 -0
  270. package/src/corpus/templates/quiz-platform/index.md +313 -0
  271. package/src/corpus/templates/quiz-platform/services/web/app/api/questions/route.js +69 -0
  272. package/src/corpus/templates/quiz-platform/services/web/app/layout.js +47 -0
  273. package/src/corpus/templates/quiz-platform/services/web/app/page.js +37 -0
  274. package/src/corpus/templates/quiz-platform/services/web/app/quiz.js +188 -0
  275. package/src/corpus/templates/quiz-platform/services/web/lib/db.js +32 -0
  276. package/src/corpus/templates/quiz-platform/services/web/package.json +16 -0
  277. package/src/corpus/templates/report/cloudgrid.yaml +228 -4
  278. package/src/corpus/templates/report/index.md +3 -5
  279. package/src/corpus/templates/restaurant-reservations/AGENTS.md +258 -0
  280. package/src/corpus/templates/restaurant-reservations/README.md +17 -0
  281. package/src/corpus/templates/restaurant-reservations/cloudgrid.yaml +258 -0
  282. package/src/corpus/templates/restaurant-reservations/index.md +62 -0
  283. package/src/corpus/templates/revenue-dashboard/README.md +75 -0
  284. package/src/corpus/templates/revenue-dashboard/cloudgrid.yaml +233 -0
  285. package/src/corpus/templates/revenue-dashboard/index.md +307 -0
  286. package/src/corpus/templates/revenue-dashboard/services/web/app/api/sales/route.js +60 -0
  287. package/src/corpus/templates/revenue-dashboard/services/web/app/layout.js +40 -0
  288. package/src/corpus/templates/revenue-dashboard/services/web/app/page.js +87 -0
  289. package/src/corpus/templates/revenue-dashboard/services/web/app/sale-form.js +63 -0
  290. package/src/corpus/templates/revenue-dashboard/services/web/lib/db.js +32 -0
  291. package/src/corpus/templates/revenue-dashboard/services/web/package.json +16 -0
  292. package/src/corpus/templates/saas-marketing/README.md +30 -0
  293. package/src/corpus/templates/saas-marketing/cloudgrid.yaml +228 -0
  294. package/src/corpus/templates/saas-marketing/index.html +212 -0
  295. package/src/corpus/templates/saas-marketing/index.md +28 -0
  296. package/src/corpus/templates/status-page/README.md +28 -0
  297. package/src/corpus/templates/status-page/cloudgrid.yaml +228 -0
  298. package/src/corpus/templates/status-page/index.html +117 -0
  299. package/src/corpus/templates/status-page/index.md +28 -0
  300. package/src/corpus/templates/subscription-management/AGENTS.md +191 -0
  301. package/src/corpus/templates/subscription-management/README.md +21 -0
  302. package/src/corpus/templates/subscription-management/cloudgrid.yaml +236 -0
  303. package/src/corpus/templates/subscription-management/index.md +73 -0
  304. package/src/corpus/templates/task-manager/README.md +72 -0
  305. package/src/corpus/templates/task-manager/cloudgrid.yaml +233 -0
  306. package/src/corpus/templates/task-manager/index.md +71 -0
  307. package/src/corpus/templates/task-manager/services/web/app/api/tasks/route.js +77 -0
  308. package/src/corpus/templates/task-manager/services/web/app/layout.js +39 -0
  309. package/src/corpus/templates/task-manager/services/web/app/page.js +33 -0
  310. package/src/corpus/templates/task-manager/services/web/app/task-list.js +110 -0
  311. package/src/corpus/templates/task-manager/services/web/lib/db.js +32 -0
  312. package/src/corpus/templates/task-manager/services/web/package.json +16 -0
  313. package/src/corpus/templates/ticket-system/README.md +71 -0
  314. package/src/corpus/templates/ticket-system/cloudgrid.yaml +233 -0
  315. package/src/corpus/templates/ticket-system/index.md +68 -0
  316. package/src/corpus/templates/ticket-system/services/web/app/api/tickets/route.js +81 -0
  317. package/src/corpus/templates/ticket-system/services/web/app/layout.js +36 -0
  318. package/src/corpus/templates/ticket-system/services/web/app/page.js +35 -0
  319. package/src/corpus/templates/ticket-system/services/web/app/ticket-queue.js +112 -0
  320. package/src/corpus/templates/ticket-system/services/web/lib/db.js +32 -0
  321. package/src/corpus/templates/ticket-system/services/web/package.json +16 -0
  322. package/src/corpus/templates/time-tracking/README.md +81 -0
  323. package/src/corpus/templates/time-tracking/cloudgrid.yaml +233 -0
  324. package/src/corpus/templates/time-tracking/index.md +298 -0
  325. package/src/corpus/templates/time-tracking/services/web/app/api/entries/route.js +66 -0
  326. package/src/corpus/templates/time-tracking/services/web/app/entry-form.js +106 -0
  327. package/src/corpus/templates/time-tracking/services/web/app/layout.js +39 -0
  328. package/src/corpus/templates/time-tracking/services/web/app/page.js +30 -0
  329. package/src/corpus/templates/time-tracking/services/web/lib/db.js +32 -0
  330. package/src/corpus/templates/time-tracking/services/web/package.json +16 -0
  331. package/src/corpus/templates/travel-booking/AGENTS.md +207 -0
  332. package/src/corpus/templates/travel-booking/README.md +17 -0
  333. package/src/corpus/templates/travel-booking/cloudgrid.yaml +249 -0
  334. package/src/corpus/templates/travel-booking/index.md +88 -0
  335. package/src/corpus/templates/waitlist/README.md +38 -0
  336. package/src/corpus/templates/waitlist/cloudgrid.yaml +228 -0
  337. package/src/corpus/templates/waitlist/index.html +69 -0
  338. package/src/corpus/templates/waitlist/index.md +39 -0
  339. package/src/corpus/templates/web-app/cloudgrid.yaml +228 -4
  340. package/src/corpus/templates/web-app/index.md +3 -5
  341. package/src/corpus/workflows/admin-dashboard.md +102 -0
  342. package/src/corpus/workflows/ai-knowledge-base.md +137 -0
  343. package/src/corpus/workflows/analytics-dashboard.md +104 -0
  344. package/src/corpus/workflows/api-dashboard.md +102 -0
  345. package/src/corpus/workflows/api-docs.md +36 -0
  346. package/src/corpus/workflows/appointment-booking.md +143 -0
  347. package/src/corpus/workflows/approval-workflow.md +124 -0
  348. package/src/corpus/workflows/billing-dashboard.md +120 -0
  349. package/src/corpus/workflows/blog-cms.md +104 -0
  350. package/src/corpus/workflows/booking-system.md +116 -0
  351. package/src/corpus/workflows/calendar-scheduler.md +134 -0
  352. package/src/corpus/workflows/changelog.md +33 -0
  353. package/src/corpus/workflows/company-website.md +46 -0
  354. package/src/corpus/workflows/course-platform.md +126 -0
  355. package/src/corpus/workflows/crm.md +101 -0
  356. package/src/corpus/workflows/directory.md +101 -0
  357. package/src/corpus/workflows/docs-site.md +35 -0
  358. package/src/corpus/workflows/erp.md +125 -0
  359. package/src/corpus/workflows/event-board.md +102 -0
  360. package/src/corpus/workflows/expense-tracker.md +102 -0
  361. package/src/corpus/workflows/feature-request-board.md +105 -0
  362. package/src/corpus/workflows/financial-dashboard.md +103 -0
  363. package/src/corpus/workflows/forum.md +128 -0
  364. package/src/corpus/workflows/hr-portal.md +115 -0
  365. package/src/corpus/workflows/internal-tools-portal.md +125 -0
  366. package/src/corpus/workflows/inventory.md +101 -0
  367. package/src/corpus/workflows/invoice.md +101 -0
  368. package/src/corpus/workflows/job-board.md +101 -0
  369. package/src/corpus/workflows/kanban.md +102 -0
  370. package/src/corpus/workflows/lms.md +113 -0
  371. package/src/corpus/workflows/marketplace.md +123 -0
  372. package/src/corpus/workflows/membership-site.md +128 -0
  373. package/src/corpus/workflows/monitoring-dashboard.md +104 -0
  374. package/src/corpus/workflows/online-store.md +114 -0
  375. package/src/corpus/workflows/portfolio.md +35 -0
  376. package/src/corpus/workflows/product-catalog.md +105 -0
  377. package/src/corpus/workflows/product-launch.md +43 -0
  378. package/src/corpus/workflows/project-management.md +106 -0
  379. package/src/corpus/workflows/property-listings.md +101 -0
  380. package/src/corpus/workflows/quiz-platform.md +105 -0
  381. package/src/corpus/workflows/restaurant-reservations.md +123 -0
  382. package/src/corpus/workflows/revenue-dashboard.md +102 -0
  383. package/src/corpus/workflows/saas-marketing.md +37 -0
  384. package/src/corpus/workflows/status-page.md +35 -0
  385. package/src/corpus/workflows/subscription-management.md +141 -0
  386. package/src/corpus/workflows/task-manager.md +101 -0
  387. package/src/corpus/workflows/ticket-system.md +101 -0
  388. package/src/corpus/workflows/time-tracking.md +104 -0
  389. package/src/corpus/workflows/travel-booking.md +115 -0
  390. package/src/corpus/workflows/waitlist.md +42 -0
@@ -1,10 +1,234 @@
1
- # static — deploys as an inspiration (instant, works on hosted) via gridctl_drop;
2
- # this yaml is only for plugging it as an OWNED static runtime (async, local
3
- # edition only). To publish the page, prefer gridctl_drop, not grid plug.
1
+ # ============================================================================
2
+ # cloudgrid.yaml — Complete Example
3
+ # ============================================================================
4
4
  #
5
- # needs: {} # none — static, no infrastructure
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
+ # THIS TEMPLATE (landing-page): a single self-contained static page. The active fields
17
+ # are exactly name + services.web{type: static, path: /}; there are no needs.
18
+ # This cloudgrid.yaml is the reference for plugging it as an OWNED static
19
+ # runtime; the fast path is to deploy it as an INSPIRATION via gridctl_drop
20
+ # (instant, and works on the hosted edition too).
21
+ # ============================================================================
22
+
23
+
24
+ # ─── IDENTITY ───────────────────────────────────────────────────────────────
25
+
26
+ # Entity slug (REQUIRED). 2-42 chars, lowercase alphanumeric + hyphens.
27
+ # Must start and end with a letter or digit.
28
+ # Becomes part of your public URL: <name>-<4hex>.<org>.cloudgrid.io
6
29
  name: landing-page
30
+
31
+ # One-line summary. Max 280 chars. If omitted, Grid Brain auto-generates one.
32
+ # description: Order processing API for the e-commerce platform
33
+
34
+ # Single emoji or short text shown as the entity icon. Max 64 chars.
35
+ # icon: "📦"
36
+
37
+ # Entity type: 'app' (default) or 'agent'. An agent is an app with an agent: block.
38
+ # kind: app
39
+
40
+
41
+ # ─── NETWORKING ─────────────────────────────────────────────────────────────
42
+
43
+ # Whether this entity serves public HTTP traffic.
44
+ # true = public URL + Ingress (default). false = internal only.
45
+ # expose: true
46
+
47
+ # Additional domain names this entity serves on (the platform URL is always active).
48
+ # custom_domains:
49
+ # - orders.example.com
50
+ # - shop.example.com
51
+
52
+
53
+ # ─── HEALTH PROBE (entity-level override) ──────────────────────────────────
54
+
55
+ # Override the default health check for the entire entity.
56
+ # probe:
57
+ # path: /healthz # HTTP path to probe (default: /).
58
+ # expected: "<500" # '<500' (default), '200', '2xx'.
59
+
60
+
61
+ # ─── DEPLOY NOTIFICATIONS ──────────────────────────────────────────────────
62
+
63
+ # Slack notification to the org's default channel on deploy failure.
64
+ # true = notify (default), false = silent.
65
+ # notify: true
66
+
67
+
68
+ # ─── SCALING ────────────────────────────────────────────────────────────────
69
+
70
+ # Replica scaling intent.
71
+ # 'auto' — platform decides from the grid tier (default).
72
+ # 'alert' — single-replica, emit a SPOF warning at plug time.
73
+ # 1-10 — explicit replica count, clamped to the grid max.
74
+ # scale: auto
75
+
76
+
77
+ # ─── INFRASTRUCTURE NEEDS ──────────────────────────────────────────────────
78
+ #
79
+ # Declare infrastructure; the platform provisions it and injects connection
80
+ # details as env vars. Nine needs: database, cache, kv, queue, pubsub, vector,
81
+ # object_storage, disk, ai. Simplest form is `true`.
82
+ #
83
+ # needs:
84
+ # # database — MongoDB. Injects DATABASE_MONGODB_URL (+ legacy MONGODB_URL).
85
+ # # true | pool | dedicated | { tier: external, secret: MY_DB }
86
+ # database: true
87
+ # # cache — Redis, LRU eviction (derived data). Injects CACHE_REDIS_URL (+ REDIS_URL).
88
+ # # true | redis | { engine: external, secret: MY_REDIS_URL }
89
+ # cache: true
90
+ # # kv — Redis, no eviction (durable: flags, idempotency). Injects KV_REDIS_URL.
91
+ # kv: true
92
+ # # queue — Redis job-queue substrate (BullMQ). Injects QUEUE_REDIS_URL.
93
+ # queue: true
94
+ # # pubsub — Redis broadcast pub/sub. Injects PUBSUB_REDIS_URL.
95
+ # pubsub: true
96
+ # # vector — pgvector on Postgres. Injects VECTOR_PGVECTOR_URL (+ PGVECTOR_URL).
97
+ # # true | pgvector | { engine: pgvector, dim: 1536 }
98
+ # vector: pgvector
99
+ # # object_storage — GCS bucket. Injects OBJECT_STORAGE_GCS_BUCKET, _GCS_REGION.
100
+ # # true | { size: 10Gi }
101
+ # object_storage: true
102
+ # # disk — persistent FS mount (PVC). Injects DISK_PATH. Pins to 1 replica.
103
+ # # true | { size: 1Gi, mount: /var/data } (forbidden: /proc /sys /dev)
104
+ # disk: true
105
+ # # ai — AI Gateway via @cloudgrid-io/ai. Injects AI_GATEWAY_URL. true | false.
106
+ # ai: true
107
+
108
+
109
+ # ─── INTER-ENTITY COMMUNICATION ────────────────────────────────────────────
110
+
111
+ # Entities this app calls (outbound). Service-account token injected per pair.
112
+ # calls:
113
+ # - org:atomic/billing-api
114
+
115
+ # Inbound caller policy — who can call YOUR entity.
116
+ # callers:
117
+ # policy: auto # 'auto' | 'manual' (default).
118
+ # scope: org # 'org' (default) | 'space' | 'explicit'.
119
+ # fallback: deny # 'deny' (default) | 'warn'.
120
+ # # allowed_apps: # required only when scope: explicit
121
+ # # - org:atomic/frontend
122
+
123
+
124
+ # ─── VAULT ──────────────────────────────────────────────────────────────────
125
+
126
+ # Map org vault items to env vars. Keys UPPER_SNAKE_CASE; values = vault item keys.
127
+ # vault:
128
+ # STRIPE_KEY: stripe-live-key
129
+ # SENDGRID_API_KEY: sendgrid-key
130
+
131
+
132
+ # ─── CONNECTORS AND HOOKS ──────────────────────────────────────────────────
133
+
134
+ # connectors:
135
+ # - id: team-slack
136
+ # target: org # 'system' | 'org'.
137
+ # channel: "#deploys"
138
+ # hooks:
139
+ # - on: deploy.failed # release.published | deploy.failed | feedback.received | entity.created
140
+ # via: team-slack
141
+ # template: "Deploy failed for {entity_name}: {error}"
142
+ # channel: "#alerts"
143
+ # triggers:
144
+ # - from: team-slack
145
+ # event: message
146
+ # channel: "#support"
147
+ # route: /webhooks/slack
148
+
149
+
150
+ # ─── LOCAL DEVELOPMENT ──────────────────────────────────────────────────────
151
+
152
+ # Config for `grid dev`. Redact fields in dev data snapshots.
153
+ # dev:
154
+ # snapshot:
155
+ # mask:
156
+ # - users.email
157
+ # - users.phone
158
+
159
+
160
+ # ─── AGENT METADATA ────────────────────────────────────────────────────────
161
+
162
+ # An agent is an app with kind: agent (above) and an agent: block.
163
+ # agent:
164
+ # purpose: Sync customer data from external CRM every night
165
+ # schedule: "0 2 * * *"
166
+ # trigger: webhook
167
+
168
+
169
+ # ─── PRIVATE RESOURCE AUTO-DEPENDENCIES ────────────────────────────────────
170
+
171
+ # When true (default), private resources are auto-injected as depends_on.
172
+ # auto_depends_on_private_requires: true
173
+
174
+
175
+ # ─── SERVICES (REQUIRED) ───────────────────────────────────────────────────
176
+ #
177
+ # At least one service is required. Key = service name (slug rules).
178
+ # Types: node, nextjs, python, static, cron.
179
+ #
7
180
  services:
8
181
  web:
182
+ # type (REQUIRED): node | nextjs | python | static | cron
9
183
  type: static
184
+ # HTTP route: '/' | '/api' | false (internal) | omitted (=false + warning).
185
+ # Only one service per entity can claim '/'.
10
186
  path: /
187
+ # Container port (default 8080; read process.env.PORT). Not for cron.
188
+ # port: 3000
189
+ # nextjs only: base_image: distroless (default) | alpine
190
+ # base_image: distroless
191
+ # node only: lang: javascript (default) | typescript
192
+ # lang: typescript
193
+ # Custom source location (default services/<name>/). '.' = project root.
194
+ # source:
195
+ # path: src/worker
196
+ # Health probe: false/omitted (TCP) | true (/health) | "/path" | {path,expected}
197
+ # health:
198
+ # path: /api/health
199
+ # expected: "200"
200
+ # Static runtime env vars (strings). Reserved: PORT, APP_NAME, SERVICE_NAME,
201
+ # NODE_ENV, MONGODB_URL, REDIS_URL, AI_GATEWAY_URL, N8N_WEBHOOK_URL, CLOUDGRID_*.
202
+ # env:
203
+ # LOG_LEVEL: info
204
+ # Sibling services/private resources that must be Ready first (no cron, no cycles).
205
+ # depends_on:
206
+ # - worker
207
+ # Per-service needs override (merges with app-level needs).
208
+ # needs:
209
+ # queue: true
210
+ # Static-only build step:
211
+ # build:
212
+ # command: npm run build
213
+ # output: dist
214
+ # env:
215
+ # VITE_API_URL: https://api.example.com
216
+ # node_version: "22" # static build step: '18'|'20'|'22'|'24' (quoted)
217
+ # Cron-only: schedule (REQUIRED), timezone (UTC|EST|PST), run (job | https URL)
218
+ # schedule: "0 9 * * 1"
219
+ # timezone: UTC
220
+ # run: job
221
+ # Verbose per-service persistence (prefer needs.disk):
222
+ # persist:
223
+ # - name: scratch
224
+ # path: /tmp/scratch
225
+ # size: 500Mi
226
+
227
+
228
+ # ============================================================================
229
+ # NOTES
230
+ # - NOT here: org:/entity_id: (→ .cloudgrid/link.json), secrets (→ grid secrets set),
231
+ # Dockerfile (platform generates from services.*.type).
232
+ # - Deploy: grid plug | Local with grid resources: grid dev
233
+ # - Full reference: docs/cloudgrid-yaml-reference.md | CLI: docs/cli-reference.md
234
+ # ============================================================================
@@ -17,11 +17,9 @@ The fillable HTML is the real template — fetch it with
17
17
  ## cloudgrid.yaml (reference only)
18
18
 
19
19
  ```yaml
20
- # static — deploys as an inspiration (instant, works on hosted) via gridctl_drop;
21
- # this yaml is only for plugging it as an OWNED static runtime (async, local
22
- # edition only). To publish the page, prefer gridctl_drop, not grid plug.
23
- #
24
- # needs: {} # none — static, no infrastructure
20
+ # On disk this file is the full-annotated reference (templates/_cloudgrid.yaml.reference) with EVERY
21
+ # field present as a comment; only the fields below are uncommented, so it
22
+ # deploys to exactly these active fields.
25
23
  name: landing-page
26
24
  services:
27
25
  web:
@@ -0,0 +1,193 @@
1
+ # AGENTS.md — lms (blueprint)
2
+
3
+ This is a **blueprint**, not runnable app code. It is the structure guide an agent
4
+ follows to build a learning management system (LMS) on CloudGrid: a training
5
+ platform where instructors publish courses (organized into modules and lessons),
6
+ students enroll and work through them, and instructors grade submissions and track
7
+ progress. Role-based auth (instructor vs. student) is the spine of the whole app.
8
+
9
+ The `cloudgrid.yaml` in this directory is complete and correct — copy it as-is.
10
+ Everything below tells you WHAT to build under `services/web/` and HOW CloudGrid
11
+ wires it together. Build the app following this; do not expect the code to exist.
12
+
13
+ ---
14
+
15
+ ## 1. File tree (build this under `services/web/`)
16
+
17
+ App code MUST live under `services/<service-name>/`. The service is named `web`,
18
+ so the CLI looks in `services/web/`. `path: /` in `cloudgrid.yaml` is the URL
19
+ mount, NOT the filesystem path. Files at the project root fail with
20
+ `Error: Service directory not found: …/services/web`.
21
+
22
+ ```
23
+ cloudgrid.yaml # this dir — name + vault + services.web(nextjs) + needs:{database:true}
24
+ services/web/package.json # next, react, react-dom, mongodb, + auth SDK (e.g. @clerk/nextjs)
25
+ services/web/middleware.js # auth middleware — protects /dashboard, /learn/*, /teach/* ; publishes session
26
+ services/web/lib/db.js # LAZY Mongo client from DATABASE_MONGODB_URL (legacy MONGODB_URL fallback)
27
+ services/web/lib/auth.js # helpers: getUserId(), getRole() from the auth provider session; requireRole()
28
+ services/web/lib/enrollment.js # server guard: isEnrolled(userId, courseId); computeProgress(userId, courseId)
29
+ services/web/app/layout.js # root layout + auth provider wrapper + inline CSS
30
+ services/web/app/page.js # course catalog (server component: lists published courses from Mongo)
31
+ services/web/app/courses/[slug]/page.js # course detail + module/lesson outline; "Enroll" vs "Continue"
32
+ services/web/app/learn/[courseSlug]/[lessonId]/page.js # lesson player — GATED: redirect unless enrolled (student)
33
+ services/web/app/dashboard/page.js # student dashboard: enrolled courses + progress bars + grades
34
+ services/web/app/teach/page.js # instructor dashboard — GATED to role=instructor: courses + submissions to grade
35
+ services/web/app/api/courses/route.js # GET list (public: published) / POST create (instructor only)
36
+ services/web/app/api/modules/route.js # GET modules+lessons for a course / POST add (instructor only)
37
+ services/web/app/api/enrollments/route.js # GET my enrollments / POST enroll student in a course
38
+ services/web/app/api/progress/route.js # POST mark-lesson-complete (upsert) ; GET course progress %
39
+ services/web/app/api/submissions/route.js # POST student submits assignment/quiz ; GET a student's submissions
40
+ services/web/app/api/grades/route.js # POST instructor grades a submission (score + feedback) ; GET a student's grades
41
+ ```
42
+
43
+ Keep it a real Next.js App Router app (`next@^15`, `react@^19`). Only add
44
+ dependencies you use: `mongodb` and one auth SDK (add `stripe` only if you sell
45
+ paid courses — see §4).
46
+
47
+ ---
48
+
49
+ ## 2. Mongo collections + fields
50
+
51
+ The grid provisions a shared MongoDB (`needs: { database: true }`). Suggested
52
+ collections (adapt names/fields freely):
53
+
54
+ - **`users`** — `{ _id, authId, name, email, role: "instructor" | "student",
55
+ createdAt }`. Mirrors the auth-provider user; `role` drives every gate. Upsert
56
+ on first login keyed by `authId`.
57
+ - **`courses`** — `{ _id, slug, title, description, instructorId, published: bool,
58
+ createdAt }`. One document per course. `instructorId` = the owning instructor.
59
+ - **`modules`** — `{ _id, courseId, title, order }`. A course is organized into
60
+ ordered modules (chapters/units).
61
+ - **`lessons`** — `{ _id, moduleId, courseId, title, order, content, videoUrl,
62
+ isFreePreview: bool }`. Ordered lessons inside a module.
63
+ - **`assignments`** — `{ _id, courseId, lessonId, title, prompt, maxScore }`.
64
+ A gradable task attached to a lesson (assignment or quiz).
65
+ - **`enrollments`** — `{ _id, userId, courseId, enrolledAt }`. The access grant —
66
+ the lesson player and submission APIs check for it.
67
+ - **`progress`** — `{ _id, userId, courseId, lessonId, completedAt }`. One doc per
68
+ student per completed lesson. Course progress % = `completed lessons / total lessons`.
69
+ - **`submissions`** — `{ _id, userId, assignmentId, courseId, answer, submittedAt }`.
70
+ A student's work turned in for an assignment.
71
+ - **`grades`** — `{ _id, submissionId, userId, assignmentId, courseId, score,
72
+ feedback, gradedBy, gradedAt }`. The instructor's grade for a submission.
73
+
74
+ Add indexes: `users.authId` (unique), `courses.slug` (unique),
75
+ `modules.courseId+order`, `lessons.moduleId+order`,
76
+ `enrollments.userId+courseId` (unique), `progress.userId+lessonId` (unique),
77
+ `submissions.userId+assignmentId` (unique).
78
+
79
+ Two access rules the whole platform hinges on — **enforce both on the server**
80
+ (in the page + API route), never only in the UI:
81
+ - **A lesson is viewable if** `isFreePreview` OR an `enrollments` doc exists for
82
+ `(userId, courseId)`.
83
+ - **Only `role: instructor`** may create courses/modules/lessons/assignments and
84
+ post grades. A student may only submit work and read their own grades/progress.
85
+
86
+ ---
87
+
88
+ ## 3. How CloudGrid injects everything
89
+
90
+ You never provision infra or set connection strings by hand. Declared needs and
91
+ vault items are injected as environment variables at `grid dev` (local) and at
92
+ runtime (after `grid plug`).
93
+
94
+ - **Mongo** — `needs: { database: true }` → the grid injects
95
+ **`DATABASE_MONGODB_URL`** (plus the legacy **`MONGODB_URL`** alias). Read
96
+ `process.env.DATABASE_MONGODB_URL || process.env.MONGODB_URL` **lazily inside a
97
+ getter** in `lib/db.js`. A top-level read (`const uri = process.env…; if (!uri)
98
+ throw`) breaks `next build`, which imports the module for route analysis before
99
+ the grid injects the var. Never hardcode a URI; never commit a secret.
100
+ - **Secrets via the `vault:` block** — the block maps org vault items to env vars:
101
+ `AUTH_PROVIDER_KEY` ← `auth-provider-key` (the server-side auth secret that lets
102
+ you verify sessions and roles). Set each vault item ONCE with
103
+ `grid secrets set <item>` (e.g. `grid secrets set auth-provider-key`); the
104
+ platform injects it as the named env var. Read it lazily too (inside the auth
105
+ client getter in `lib/auth.js`), not at module top level. If you add paid
106
+ courses, map `STRIPE_KEY`/`STRIPE_WEBHOOK_SECRET` the same way.
107
+ - **AI (optional — auto-grading / quiz generation / a study tutor)** — add
108
+ `needs: { ai: true }` → the grid injects **`AI_GATEWAY_URL`**; call it via
109
+ `@cloudgrid-io/ai`. Not enabled in this blueprint; add the need if you want it.
110
+
111
+ Reserved env var names you must NOT set yourself: `PORT`, `NODE_ENV`,
112
+ `DATABASE_MONGODB_URL`/`MONGODB_URL`, `AI_GATEWAY_URL`, `CLOUDGRID_*`.
113
+
114
+ ---
115
+
116
+ ## 4. Wiring auth (roles) + optional payments
117
+
118
+ ### Auth + roles (provider SDK) — the core of the LMS
119
+ Use a hosted auth provider SDK (e.g. Clerk or Auth0) rather than rolling your own.
120
+ Role-based access (instructor vs. student) is what separates an LMS from a plain
121
+ content site, so wire it first.
122
+
123
+ 1. Add the SDK to `package.json` (e.g. `@clerk/nextjs`).
124
+ 2. Wrap `app/layout.js` in the provider; add `middleware.js` to protect
125
+ `/dashboard`, `/learn/*` (any signed-in user) and `/teach/*` (instructors only).
126
+ 3. The **publishable** key is a non-secret client env var → set it with
127
+ `grid env` (e.g. `grid env NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=…`). The **secret**
128
+ server key comes from the vault → `AUTH_PROVIDER_KEY` (mapped in `cloudgrid.yaml`),
129
+ read lazily in `lib/auth.js`.
130
+ 4. `lib/auth.js` exposes `getUserId()` and `getRole()` reading the provider's
131
+ server session, plus `requireRole("instructor")` that throws/redirects for
132
+ students. Every instructor-only API route (`/api/courses` POST,
133
+ `/api/modules` POST, `/api/grades` POST) calls `requireRole("instructor")`
134
+ server-side. Store the role on the `users` doc and/or in the provider's
135
+ user metadata; upsert the `users` doc on first login keyed by `authId`.
136
+
137
+ ### Grading flow (the LMS-specific loop)
138
+ 1. A student POSTs to `/api/submissions` (guarded by `isEnrolled`) to turn in an
139
+ assignment answer → one `submissions` doc per `(userId, assignmentId)`.
140
+ 2. The instructor sees ungraded submissions on `/teach`, and POSTs to
141
+ `/api/grades` (guarded by `requireRole("instructor")`) with `score` + `feedback`
142
+ → a `grades` doc referencing the `submissionId`. Never let a client set its own
143
+ score; derive `gradedBy` from the server session.
144
+ 3. The student reads their grades on `/dashboard` via `/api/grades` GET, scoped to
145
+ `getUserId()` so students only ever see their own grades.
146
+
147
+ ### Payments (Stripe) — OPTIONAL, only for paid courses
148
+ If courses are sold rather than freely enrollable, add `stripe` to `package.json`
149
+ and a `vault:` mapping for `STRIPE_KEY` + `STRIPE_WEBHOOK_SECRET`:
150
+ 1. `lib/stripe.js` builds the Stripe client lazily from `process.env.STRIPE_KEY`.
151
+ 2. **Checkout route** `app/api/checkout/route.js`: POST with a `courseId`, read the
152
+ course price server-side, create a Stripe Checkout Session (`payment` mode) with
153
+ `client_reference_id = userId` and `metadata.courseId`, return `session.url`.
154
+ Never trust a price sent from the client.
155
+ 3. **Webhook route** `app/api/webhooks/stripe/route.js`: verify the signature with
156
+ `STRIPE_WEBHOOK_SECRET` (`stripe.webhooks.constructEvent(rawBody, sig, secret)`
157
+ — read the RAW body, do not JSON-parse first). On `checkout.session.completed`,
158
+ upsert an `enrollments` doc. This webhook — not the checkout redirect — grants
159
+ access. Register the webhook URL (`https://<live-url>/api/webhooks/stripe`) in
160
+ the Stripe dashboard after the first deploy, then set `stripe-webhook-secret`.
161
+
162
+ ---
163
+
164
+ ## 5. Deploy steps
165
+
166
+ A runtime deploy is **asynchronous** and requires the **local edition** (§6).
167
+
168
+ 1. **`grid init`** an app named `lms`. `init` creates the entity +
169
+ `.cloudgrid/link.json` and writes a `cloudgrid.yaml` with an empty
170
+ `services: {}`. Run it FIRST — `plug` needs a linked directory.
171
+ 2. **Fill** — replace the generated `cloudgrid.yaml` with the one in this template
172
+ (name + vault + `services.web` nextjs + `needs: { database: true }`), and write
173
+ the app under `services/web/` per the tree above.
174
+ 3. **Set secrets** — `grid secrets set auth-provider-key` (and, if selling courses,
175
+ `grid secrets set stripe-live-key` + `grid secrets set stripe-webhook-secret`).
176
+ Set non-secret client config with `grid env` (e.g. the auth publishable key).
177
+ Do NOT set the DB vars — the grid injects them.
178
+ 4. **`grid plug`** — builds + deploys `services/web/`. The first response is
179
+ `status: building`, NOT a live URL. Poll `grid status` (or the returned
180
+ poll_url) until it is live; surface a liveness signal while it builds, never a
181
+ bare silent wait. Only then return the live app URL.
182
+ 5. **Iterate** — re-plug the SAME entity so it updates the same URL. (If you added
183
+ Stripe, wire the webhook to the live URL first — §4.)
184
+
185
+ ---
186
+
187
+ ## 6. Edition note
188
+
189
+ An LMS is a built + deployed **runtime** container. It requires the **local
190
+ edition** (Claude Desktop / Claude Code) or the CLI. On the **hosted** edition
191
+ (Claude Web / hosted MCP) you cannot build a runtime app — hosted is inline-only
192
+ and can only publish static pages. If you are on hosted, say so plainly and stop
193
+ the runtime path (a static course *landing* page is the only thing hosted can ship).
@@ -0,0 +1,27 @@
1
+ # lms template — blueprint (structure + cloudgrid.yaml)
2
+
3
+ A learning management system / training platform: instructors publish courses
4
+ organized into modules and lessons, students enroll and progress through them,
5
+ and instructors grade submissions and track each student's progress — a
6
+ persistent Next.js + Mongo app with role-based (instructor/student) auth. This is
7
+ a **blueprint**: it ships the correct `cloudgrid.yaml` and an `AGENTS.md`
8
+ structure guide (file tree, Mongo collections, CloudGrid env/vault wiring, the
9
+ auth-role + grading flow, deploy steps), not runnable app code. Adapt the
10
+ structure and build the app under `services/web/`.
11
+
12
+ ## What's here
13
+
14
+ - **`cloudgrid.yaml`** — full-annotated reference with only the active fields
15
+ uncommented: `name`, a `vault:` block (`AUTH_PROVIDER_KEY`), `services.web`
16
+ (type: nextjs, path: /), and `needs: { database: true }`. Copy it as-is.
17
+ - **`AGENTS.md`** — the structure guide. Read it before building: it is the
18
+ CloudGrid-specific spec for the file tree, collections, secret injection, the
19
+ instructor/student role gates + grading loop, and the async runtime deploy.
20
+
21
+ ## Blueprint: structure + cloudgrid.yaml, adapt and build
22
+
23
+ Read `AGENTS.md`, then build the app following it — put the code under
24
+ `services/web/`, read `DATABASE_MONGODB_URL` (legacy `MONGODB_URL` fallback) and
25
+ the vault-injected `AUTH_PROVIDER_KEY` lazily inside getters, enforce the
26
+ instructor/student role gates on the server, declare `needs: { database: true }`,
27
+ and deploy with `grid plug` (async — poll to a live URL; local edition only).