@cloudgrid-io/mcp 0.13.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.
- package/package.json +1 -1
- package/src/corpus/capability-map.md +68 -7
- package/src/corpus/templates/_cloudgrid.yaml.reference +228 -0
- package/src/corpus/templates/admin-dashboard/cloudgrid.yaml +226 -8
- package/src/corpus/templates/admin-dashboard/index.md +3 -0
- package/src/corpus/templates/ai-app/cloudgrid.yaml +225 -11
- package/src/corpus/templates/ai-app/index.md +3 -11
- package/src/corpus/templates/ai-knowledge-base/AGENTS.md +254 -0
- package/src/corpus/templates/ai-knowledge-base/README.md +28 -0
- package/src/corpus/templates/ai-knowledge-base/cloudgrid.yaml +238 -0
- package/src/corpus/templates/ai-knowledge-base/index.md +81 -0
- package/src/corpus/templates/analytics-dashboard/README.md +85 -0
- package/src/corpus/templates/analytics-dashboard/cloudgrid.yaml +232 -0
- package/src/corpus/templates/analytics-dashboard/index.md +316 -0
- package/src/corpus/templates/analytics-dashboard/services/web/app/api/events/route.js +60 -0
- package/src/corpus/templates/analytics-dashboard/services/web/app/event-form.js +100 -0
- package/src/corpus/templates/analytics-dashboard/services/web/app/layout.js +41 -0
- package/src/corpus/templates/analytics-dashboard/services/web/app/page.js +54 -0
- package/src/corpus/templates/analytics-dashboard/services/web/lib/db.js +32 -0
- package/src/corpus/templates/analytics-dashboard/services/web/package.json +16 -0
- package/src/corpus/templates/api-dashboard/README.md +84 -0
- package/src/corpus/templates/api-dashboard/cloudgrid.yaml +233 -0
- package/src/corpus/templates/api-dashboard/index.md +310 -0
- package/src/corpus/templates/api-dashboard/services/web/app/api/requests/route.js +62 -0
- package/src/corpus/templates/api-dashboard/services/web/app/dashboard.js +156 -0
- package/src/corpus/templates/api-dashboard/services/web/app/layout.js +42 -0
- package/src/corpus/templates/api-dashboard/services/web/app/page.js +39 -0
- package/src/corpus/templates/api-dashboard/services/web/lib/db.js +32 -0
- package/src/corpus/templates/api-dashboard/services/web/package.json +16 -0
- package/src/corpus/templates/api-docs/cloudgrid.yaml +222 -4
- package/src/corpus/templates/api-docs/index.md +3 -5
- package/src/corpus/templates/api-service/cloudgrid.yaml +224 -9
- package/src/corpus/templates/api-service/index.md +3 -11
- package/src/corpus/templates/app-with-data/cloudgrid.yaml +226 -8
- package/src/corpus/templates/app-with-data/index.md +3 -8
- package/src/corpus/templates/appointment-booking/AGENTS.md +223 -0
- package/src/corpus/templates/appointment-booking/README.md +16 -0
- package/src/corpus/templates/appointment-booking/cloudgrid.yaml +250 -0
- package/src/corpus/templates/appointment-booking/index.md +72 -0
- package/src/corpus/templates/approval-workflow/AGENTS.md +170 -0
- package/src/corpus/templates/approval-workflow/README.md +12 -0
- package/src/corpus/templates/approval-workflow/cloudgrid.yaml +237 -0
- package/src/corpus/templates/approval-workflow/index.md +58 -0
- package/src/corpus/templates/billing-dashboard/AGENTS.md +199 -0
- package/src/corpus/templates/billing-dashboard/README.md +18 -0
- package/src/corpus/templates/billing-dashboard/cloudgrid.yaml +235 -0
- package/src/corpus/templates/billing-dashboard/index.md +87 -0
- package/src/corpus/templates/blog-cms/README.md +94 -0
- package/src/corpus/templates/blog-cms/cloudgrid.yaml +233 -0
- package/src/corpus/templates/blog-cms/index.md +358 -0
- package/src/corpus/templates/blog-cms/services/web/app/admin/admin-editor.js +133 -0
- package/src/corpus/templates/blog-cms/services/web/app/admin/page.js +33 -0
- package/src/corpus/templates/blog-cms/services/web/app/api/posts/route.js +84 -0
- package/src/corpus/templates/blog-cms/services/web/app/layout.js +47 -0
- package/src/corpus/templates/blog-cms/services/web/app/page.js +56 -0
- package/src/corpus/templates/blog-cms/services/web/app/posts/[slug]/page.js +45 -0
- package/src/corpus/templates/blog-cms/services/web/lib/db.js +32 -0
- package/src/corpus/templates/blog-cms/services/web/package.json +16 -0
- package/src/corpus/templates/booking-system/AGENTS.md +189 -0
- package/src/corpus/templates/booking-system/README.md +17 -0
- package/src/corpus/templates/booking-system/cloudgrid.yaml +248 -0
- package/src/corpus/templates/booking-system/index.md +86 -0
- package/src/corpus/templates/calendar-scheduler/AGENTS.md +226 -0
- package/src/corpus/templates/calendar-scheduler/README.md +25 -0
- package/src/corpus/templates/calendar-scheduler/cloudgrid.yaml +259 -0
- package/src/corpus/templates/calendar-scheduler/index.md +85 -0
- package/src/corpus/templates/changelog/cloudgrid.yaml +222 -4
- package/src/corpus/templates/changelog/index.md +3 -5
- package/src/corpus/templates/company-website/README.md +54 -0
- package/src/corpus/templates/company-website/cloudgrid.yaml +233 -0
- package/src/corpus/templates/company-website/index.html +309 -0
- package/src/corpus/templates/company-website/index.md +29 -0
- package/src/corpus/templates/course-platform/AGENTS.md +161 -0
- package/src/corpus/templates/course-platform/README.md +26 -0
- package/src/corpus/templates/course-platform/cloudgrid.yaml +237 -0
- package/src/corpus/templates/course-platform/index.md +70 -0
- package/src/corpus/templates/crm/cloudgrid.yaml +226 -8
- package/src/corpus/templates/crm/index.md +3 -0
- package/src/corpus/templates/dashboard/cloudgrid.yaml +228 -4
- package/src/corpus/templates/dashboard/index.md +3 -5
- package/src/corpus/templates/deck/cloudgrid.yaml +228 -4
- package/src/corpus/templates/deck/index.md +3 -5
- package/src/corpus/templates/directory/README.md +75 -0
- package/src/corpus/templates/directory/cloudgrid.yaml +233 -0
- package/src/corpus/templates/directory/index.md +334 -0
- package/src/corpus/templates/directory/services/web/app/api/entries/route.js +63 -0
- package/src/corpus/templates/directory/services/web/app/directory-list.js +146 -0
- package/src/corpus/templates/directory/services/web/app/layout.js +44 -0
- package/src/corpus/templates/directory/services/web/app/page.js +38 -0
- package/src/corpus/templates/directory/services/web/lib/db.js +32 -0
- package/src/corpus/templates/directory/services/web/package.json +16 -0
- package/src/corpus/templates/docs-site/cloudgrid.yaml +222 -4
- package/src/corpus/templates/docs-site/index.md +3 -5
- package/src/corpus/templates/erp/AGENTS.md +116 -0
- package/src/corpus/templates/erp/README.md +17 -0
- package/src/corpus/templates/erp/cloudgrid.yaml +235 -0
- package/src/corpus/templates/erp/index.md +81 -0
- package/src/corpus/templates/event-board/README.md +74 -0
- package/src/corpus/templates/event-board/cloudgrid.yaml +233 -0
- package/src/corpus/templates/event-board/index.md +299 -0
- package/src/corpus/templates/event-board/services/web/app/api/events/route.js +61 -0
- package/src/corpus/templates/event-board/services/web/app/event-form.js +118 -0
- package/src/corpus/templates/event-board/services/web/app/layout.js +39 -0
- package/src/corpus/templates/event-board/services/web/app/page.js +34 -0
- package/src/corpus/templates/event-board/services/web/lib/db.js +32 -0
- package/src/corpus/templates/event-board/services/web/package.json +16 -0
- package/src/corpus/templates/expense-tracker/README.md +76 -0
- package/src/corpus/templates/expense-tracker/cloudgrid.yaml +233 -0
- package/src/corpus/templates/expense-tracker/index.md +305 -0
- package/src/corpus/templates/expense-tracker/services/web/app/api/expenses/route.js +61 -0
- package/src/corpus/templates/expense-tracker/services/web/app/expense-form.js +145 -0
- package/src/corpus/templates/expense-tracker/services/web/app/layout.js +42 -0
- package/src/corpus/templates/expense-tracker/services/web/app/page.js +34 -0
- package/src/corpus/templates/expense-tracker/services/web/lib/db.js +32 -0
- package/src/corpus/templates/expense-tracker/services/web/package.json +16 -0
- package/src/corpus/templates/feature-request-board/README.md +87 -0
- package/src/corpus/templates/feature-request-board/cloudgrid.yaml +233 -0
- package/src/corpus/templates/feature-request-board/index.md +317 -0
- package/src/corpus/templates/feature-request-board/services/web/app/api/requests/route.js +92 -0
- package/src/corpus/templates/feature-request-board/services/web/app/board.js +91 -0
- package/src/corpus/templates/feature-request-board/services/web/app/layout.js +43 -0
- package/src/corpus/templates/feature-request-board/services/web/app/page.js +35 -0
- package/src/corpus/templates/feature-request-board/services/web/lib/db.js +32 -0
- package/src/corpus/templates/feature-request-board/services/web/package.json +16 -0
- package/src/corpus/templates/financial-dashboard/README.md +80 -0
- package/src/corpus/templates/financial-dashboard/cloudgrid.yaml +233 -0
- package/src/corpus/templates/financial-dashboard/index.md +326 -0
- package/src/corpus/templates/financial-dashboard/services/web/app/api/entries/route.js +63 -0
- package/src/corpus/templates/financial-dashboard/services/web/app/entry-board.js +130 -0
- package/src/corpus/templates/financial-dashboard/services/web/app/layout.js +46 -0
- package/src/corpus/templates/financial-dashboard/services/web/app/page.js +31 -0
- package/src/corpus/templates/financial-dashboard/services/web/lib/db.js +32 -0
- package/src/corpus/templates/financial-dashboard/services/web/package.json +16 -0
- package/src/corpus/templates/forum/AGENTS.md +196 -0
- package/src/corpus/templates/forum/README.md +12 -0
- package/src/corpus/templates/forum/cloudgrid.yaml +237 -0
- package/src/corpus/templates/forum/index.md +66 -0
- package/src/corpus/templates/hr-portal/AGENTS.md +174 -0
- package/src/corpus/templates/hr-portal/README.md +14 -0
- package/src/corpus/templates/hr-portal/cloudgrid.yaml +237 -0
- package/src/corpus/templates/hr-portal/index.md +56 -0
- package/src/corpus/templates/internal-tools-portal/AGENTS.md +201 -0
- package/src/corpus/templates/internal-tools-portal/README.md +17 -0
- package/src/corpus/templates/internal-tools-portal/cloudgrid.yaml +237 -0
- package/src/corpus/templates/internal-tools-portal/index.md +62 -0
- package/src/corpus/templates/inventory/README.md +71 -0
- package/src/corpus/templates/inventory/cloudgrid.yaml +233 -0
- package/src/corpus/templates/inventory/index.md +68 -0
- package/src/corpus/templates/inventory/services/web/app/api/items/route.js +88 -0
- package/src/corpus/templates/inventory/services/web/app/inventory-manager.js +101 -0
- package/src/corpus/templates/inventory/services/web/app/layout.js +36 -0
- package/src/corpus/templates/inventory/services/web/app/page.js +37 -0
- package/src/corpus/templates/inventory/services/web/lib/db.js +32 -0
- package/src/corpus/templates/inventory/services/web/package.json +16 -0
- package/src/corpus/templates/invoice/README.md +71 -0
- package/src/corpus/templates/invoice/cloudgrid.yaml +233 -0
- package/src/corpus/templates/invoice/index.md +68 -0
- package/src/corpus/templates/invoice/services/web/app/api/invoices/route.js +82 -0
- package/src/corpus/templates/invoice/services/web/app/invoice-manager.js +101 -0
- package/src/corpus/templates/invoice/services/web/app/layout.js +35 -0
- package/src/corpus/templates/invoice/services/web/app/page.js +34 -0
- package/src/corpus/templates/invoice/services/web/lib/db.js +32 -0
- package/src/corpus/templates/invoice/services/web/package.json +16 -0
- package/src/corpus/templates/job-board/README.md +71 -0
- package/src/corpus/templates/job-board/cloudgrid.yaml +233 -0
- package/src/corpus/templates/job-board/index.md +68 -0
- package/src/corpus/templates/job-board/services/web/app/api/jobs/route.js +66 -0
- package/src/corpus/templates/job-board/services/web/app/job-board.js +73 -0
- package/src/corpus/templates/job-board/services/web/app/layout.js +35 -0
- package/src/corpus/templates/job-board/services/web/app/page.js +32 -0
- package/src/corpus/templates/job-board/services/web/lib/db.js +32 -0
- package/src/corpus/templates/job-board/services/web/package.json +16 -0
- package/src/corpus/templates/kanban/cloudgrid.yaml +226 -8
- package/src/corpus/templates/kanban/index.md +3 -0
- package/src/corpus/templates/landing-page/cloudgrid.yaml +228 -4
- package/src/corpus/templates/landing-page/index.md +3 -5
- package/src/corpus/templates/lms/AGENTS.md +193 -0
- package/src/corpus/templates/lms/README.md +27 -0
- package/src/corpus/templates/lms/cloudgrid.yaml +237 -0
- package/src/corpus/templates/lms/index.md +79 -0
- package/src/corpus/templates/marketplace/AGENTS.md +208 -0
- package/src/corpus/templates/marketplace/README.md +22 -0
- package/src/corpus/templates/marketplace/cloudgrid.yaml +233 -0
- package/src/corpus/templates/marketplace/index.md +76 -0
- package/src/corpus/templates/membership-site/AGENTS.md +160 -0
- package/src/corpus/templates/membership-site/README.md +18 -0
- package/src/corpus/templates/membership-site/cloudgrid.yaml +236 -0
- package/src/corpus/templates/membership-site/index.md +66 -0
- package/src/corpus/templates/monitoring-dashboard/README.md +84 -0
- package/src/corpus/templates/monitoring-dashboard/cloudgrid.yaml +233 -0
- package/src/corpus/templates/monitoring-dashboard/index.md +328 -0
- package/src/corpus/templates/monitoring-dashboard/services/web/app/api/checks/route.js +76 -0
- package/src/corpus/templates/monitoring-dashboard/services/web/app/check-form.js +124 -0
- package/src/corpus/templates/monitoring-dashboard/services/web/app/layout.js +44 -0
- package/src/corpus/templates/monitoring-dashboard/services/web/app/page.js +49 -0
- package/src/corpus/templates/monitoring-dashboard/services/web/lib/db.js +32 -0
- package/src/corpus/templates/monitoring-dashboard/services/web/package.json +16 -0
- package/src/corpus/templates/online-store/AGENTS.md +153 -0
- package/src/corpus/templates/online-store/README.md +16 -0
- package/src/corpus/templates/online-store/cloudgrid.yaml +234 -0
- package/src/corpus/templates/online-store/index.md +81 -0
- package/src/corpus/templates/portfolio/cloudgrid.yaml +222 -4
- package/src/corpus/templates/portfolio/index.md +3 -5
- package/src/corpus/templates/product-catalog/README.md +74 -0
- package/src/corpus/templates/product-catalog/cloudgrid.yaml +232 -0
- package/src/corpus/templates/product-catalog/index.md +330 -0
- package/src/corpus/templates/product-catalog/services/web/app/api/products/route.js +69 -0
- package/src/corpus/templates/product-catalog/services/web/app/catalog.js +153 -0
- package/src/corpus/templates/product-catalog/services/web/app/layout.js +49 -0
- package/src/corpus/templates/product-catalog/services/web/app/page.js +36 -0
- package/src/corpus/templates/product-catalog/services/web/lib/db.js +32 -0
- package/src/corpus/templates/product-catalog/services/web/package.json +16 -0
- package/src/corpus/templates/product-launch/README.md +46 -0
- package/src/corpus/templates/product-launch/cloudgrid.yaml +234 -0
- package/src/corpus/templates/product-launch/index.html +320 -0
- package/src/corpus/templates/product-launch/index.md +34 -0
- package/src/corpus/templates/project-management/README.md +83 -0
- package/src/corpus/templates/project-management/cloudgrid.yaml +233 -0
- package/src/corpus/templates/project-management/index.md +346 -0
- package/src/corpus/templates/project-management/services/web/app/api/projects/route.js +48 -0
- package/src/corpus/templates/project-management/services/web/app/api/tasks/route.js +85 -0
- package/src/corpus/templates/project-management/services/web/app/board.js +182 -0
- package/src/corpus/templates/project-management/services/web/app/layout.js +45 -0
- package/src/corpus/templates/project-management/services/web/app/page.js +49 -0
- package/src/corpus/templates/project-management/services/web/lib/db.js +32 -0
- package/src/corpus/templates/project-management/services/web/package.json +16 -0
- package/src/corpus/templates/property-listings/README.md +76 -0
- package/src/corpus/templates/property-listings/cloudgrid.yaml +233 -0
- package/src/corpus/templates/property-listings/index.md +335 -0
- package/src/corpus/templates/property-listings/services/web/app/api/properties/route.js +73 -0
- package/src/corpus/templates/property-listings/services/web/app/layout.js +45 -0
- package/src/corpus/templates/property-listings/services/web/app/listings.js +152 -0
- package/src/corpus/templates/property-listings/services/web/app/page.js +53 -0
- package/src/corpus/templates/property-listings/services/web/lib/db.js +32 -0
- package/src/corpus/templates/property-listings/services/web/package.json +16 -0
- package/src/corpus/templates/quiz-platform/README.md +84 -0
- package/src/corpus/templates/quiz-platform/cloudgrid.yaml +233 -0
- package/src/corpus/templates/quiz-platform/index.md +313 -0
- package/src/corpus/templates/quiz-platform/services/web/app/api/questions/route.js +69 -0
- package/src/corpus/templates/quiz-platform/services/web/app/layout.js +47 -0
- package/src/corpus/templates/quiz-platform/services/web/app/page.js +37 -0
- package/src/corpus/templates/quiz-platform/services/web/app/quiz.js +188 -0
- package/src/corpus/templates/quiz-platform/services/web/lib/db.js +32 -0
- package/src/corpus/templates/quiz-platform/services/web/package.json +16 -0
- package/src/corpus/templates/report/cloudgrid.yaml +228 -4
- package/src/corpus/templates/report/index.md +3 -5
- package/src/corpus/templates/restaurant-reservations/AGENTS.md +258 -0
- package/src/corpus/templates/restaurant-reservations/README.md +17 -0
- package/src/corpus/templates/restaurant-reservations/cloudgrid.yaml +258 -0
- package/src/corpus/templates/restaurant-reservations/index.md +62 -0
- package/src/corpus/templates/revenue-dashboard/README.md +75 -0
- package/src/corpus/templates/revenue-dashboard/cloudgrid.yaml +233 -0
- package/src/corpus/templates/revenue-dashboard/index.md +307 -0
- package/src/corpus/templates/revenue-dashboard/services/web/app/api/sales/route.js +60 -0
- package/src/corpus/templates/revenue-dashboard/services/web/app/layout.js +40 -0
- package/src/corpus/templates/revenue-dashboard/services/web/app/page.js +87 -0
- package/src/corpus/templates/revenue-dashboard/services/web/app/sale-form.js +63 -0
- package/src/corpus/templates/revenue-dashboard/services/web/lib/db.js +32 -0
- package/src/corpus/templates/revenue-dashboard/services/web/package.json +16 -0
- package/src/corpus/templates/saas-marketing/cloudgrid.yaml +222 -4
- package/src/corpus/templates/saas-marketing/index.md +3 -5
- package/src/corpus/templates/status-page/cloudgrid.yaml +222 -4
- package/src/corpus/templates/status-page/index.md +3 -5
- package/src/corpus/templates/subscription-management/AGENTS.md +191 -0
- package/src/corpus/templates/subscription-management/README.md +21 -0
- package/src/corpus/templates/subscription-management/cloudgrid.yaml +236 -0
- package/src/corpus/templates/subscription-management/index.md +73 -0
- package/src/corpus/templates/task-manager/cloudgrid.yaml +226 -8
- package/src/corpus/templates/task-manager/index.md +3 -0
- package/src/corpus/templates/ticket-system/README.md +71 -0
- package/src/corpus/templates/ticket-system/cloudgrid.yaml +233 -0
- package/src/corpus/templates/ticket-system/index.md +68 -0
- package/src/corpus/templates/ticket-system/services/web/app/api/tickets/route.js +81 -0
- package/src/corpus/templates/ticket-system/services/web/app/layout.js +36 -0
- package/src/corpus/templates/ticket-system/services/web/app/page.js +35 -0
- package/src/corpus/templates/ticket-system/services/web/app/ticket-queue.js +112 -0
- package/src/corpus/templates/ticket-system/services/web/lib/db.js +32 -0
- package/src/corpus/templates/ticket-system/services/web/package.json +16 -0
- package/src/corpus/templates/time-tracking/README.md +81 -0
- package/src/corpus/templates/time-tracking/cloudgrid.yaml +233 -0
- package/src/corpus/templates/time-tracking/index.md +298 -0
- package/src/corpus/templates/time-tracking/services/web/app/api/entries/route.js +66 -0
- package/src/corpus/templates/time-tracking/services/web/app/entry-form.js +106 -0
- package/src/corpus/templates/time-tracking/services/web/app/layout.js +39 -0
- package/src/corpus/templates/time-tracking/services/web/app/page.js +30 -0
- package/src/corpus/templates/time-tracking/services/web/lib/db.js +32 -0
- package/src/corpus/templates/time-tracking/services/web/package.json +16 -0
- package/src/corpus/templates/travel-booking/AGENTS.md +207 -0
- package/src/corpus/templates/travel-booking/README.md +17 -0
- package/src/corpus/templates/travel-booking/cloudgrid.yaml +249 -0
- package/src/corpus/templates/travel-booking/index.md +88 -0
- package/src/corpus/templates/waitlist/cloudgrid.yaml +222 -4
- package/src/corpus/templates/waitlist/index.md +3 -5
- package/src/corpus/templates/web-app/cloudgrid.yaml +228 -4
- package/src/corpus/templates/web-app/index.md +3 -5
- package/src/corpus/workflows/ai-knowledge-base.md +137 -0
- package/src/corpus/workflows/analytics-dashboard.md +104 -0
- package/src/corpus/workflows/api-dashboard.md +102 -0
- package/src/corpus/workflows/appointment-booking.md +143 -0
- package/src/corpus/workflows/approval-workflow.md +124 -0
- package/src/corpus/workflows/billing-dashboard.md +120 -0
- package/src/corpus/workflows/blog-cms.md +104 -0
- package/src/corpus/workflows/booking-system.md +116 -0
- package/src/corpus/workflows/calendar-scheduler.md +134 -0
- package/src/corpus/workflows/company-website.md +46 -0
- package/src/corpus/workflows/course-platform.md +126 -0
- package/src/corpus/workflows/directory.md +101 -0
- package/src/corpus/workflows/erp.md +125 -0
- package/src/corpus/workflows/event-board.md +102 -0
- package/src/corpus/workflows/expense-tracker.md +102 -0
- package/src/corpus/workflows/feature-request-board.md +105 -0
- package/src/corpus/workflows/financial-dashboard.md +103 -0
- package/src/corpus/workflows/forum.md +128 -0
- package/src/corpus/workflows/hr-portal.md +115 -0
- package/src/corpus/workflows/internal-tools-portal.md +125 -0
- package/src/corpus/workflows/inventory.md +101 -0
- package/src/corpus/workflows/invoice.md +101 -0
- package/src/corpus/workflows/job-board.md +101 -0
- package/src/corpus/workflows/lms.md +113 -0
- package/src/corpus/workflows/marketplace.md +123 -0
- package/src/corpus/workflows/membership-site.md +128 -0
- package/src/corpus/workflows/monitoring-dashboard.md +104 -0
- package/src/corpus/workflows/online-store.md +114 -0
- package/src/corpus/workflows/product-catalog.md +105 -0
- package/src/corpus/workflows/product-launch.md +43 -0
- package/src/corpus/workflows/project-management.md +106 -0
- package/src/corpus/workflows/property-listings.md +101 -0
- package/src/corpus/workflows/quiz-platform.md +105 -0
- package/src/corpus/workflows/restaurant-reservations.md +123 -0
- package/src/corpus/workflows/revenue-dashboard.md +102 -0
- package/src/corpus/workflows/subscription-management.md +141 -0
- package/src/corpus/workflows/ticket-system.md +101 -0
- package/src/corpus/workflows/time-tracking.md +104 -0
- package/src/corpus/workflows/travel-booking.md +115 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# AGENTS.md — course-platform (blueprint)
|
|
2
|
+
|
|
3
|
+
This is a **blueprint**, not runnable app code. It is the structure guide an agent
|
|
4
|
+
follows to build a Teachable-style course platform on CloudGrid: sell online
|
|
5
|
+
courses, gate lessons behind purchase, and track per-student lesson progress.
|
|
6
|
+
|
|
7
|
+
The `cloudgrid.yaml` in this directory is complete and correct — copy it as-is.
|
|
8
|
+
Everything below tells you WHAT to build under `services/web/` and HOW CloudGrid
|
|
9
|
+
wires it together. Build the app following this; do not expect the code to exist.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. File tree (build this under `services/web/`)
|
|
14
|
+
|
|
15
|
+
App code MUST live under `services/<service-name>/`. The service is named `web`,
|
|
16
|
+
so the CLI looks in `services/web/`. `path: /` in `cloudgrid.yaml` is the URL
|
|
17
|
+
mount, NOT the filesystem path. Files at the project root fail with
|
|
18
|
+
`Error: Service directory not found: …/services/web`.
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
cloudgrid.yaml # this dir — name + vault + services.web(nextjs) + needs:{database:true}
|
|
22
|
+
services/web/package.json # next, react, react-dom, mongodb, stripe, + auth SDK (e.g. @clerk/nextjs)
|
|
23
|
+
services/web/middleware.js # auth middleware — protects /dashboard, /learn/* ; publishes user session
|
|
24
|
+
services/web/lib/db.js # LAZY Mongo client from DATABASE_MONGODB_URL (legacy MONGODB_URL fallback)
|
|
25
|
+
services/web/lib/stripe.js # LAZY Stripe client from process.env.STRIPE_KEY (vault-injected)
|
|
26
|
+
services/web/lib/auth.js # helper: current userId from the auth provider session
|
|
27
|
+
services/web/app/layout.js # root layout + auth provider wrapper + inline CSS
|
|
28
|
+
services/web/app/page.js # course catalog (server component: lists published courses from Mongo)
|
|
29
|
+
services/web/app/courses/[slug]/page.js # course detail + lesson list; "Buy" (unenrolled) vs "Continue" (enrolled)
|
|
30
|
+
services/web/app/learn/[courseSlug]/[lessonId]/page.js # lesson player — GATED: 403/redirect unless enrolled
|
|
31
|
+
services/web/app/dashboard/page.js # student dashboard: enrolled courses + progress bars
|
|
32
|
+
services/web/app/api/courses/route.js # GET list / POST create (instructor)
|
|
33
|
+
services/web/app/api/enrollments/route.js # GET my enrollments (derived from paid checkouts)
|
|
34
|
+
services/web/app/api/progress/route.js # POST mark-lesson-complete (upsert into progress); GET course progress
|
|
35
|
+
services/web/app/api/checkout/route.js # POST → create Stripe Checkout Session for a course, return session URL
|
|
36
|
+
services/web/app/api/webhooks/stripe/route.js # POST ← Stripe: on checkout.session.completed → create enrollment
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Keep it a real Next.js App Router app (`next@^15`, `react@^19`). Only add
|
|
40
|
+
dependencies you use: `mongodb`, `stripe`, and one auth SDK.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 2. Mongo collections + fields
|
|
45
|
+
|
|
46
|
+
The grid provisions a shared MongoDB (`needs: { database: true }`). Suggested
|
|
47
|
+
collections (adapt names/fields freely):
|
|
48
|
+
|
|
49
|
+
- **`courses`** — `{ _id, slug, title, description, priceCents, currency,
|
|
50
|
+
instructorId, published: bool, createdAt }`. One document per sellable course.
|
|
51
|
+
- **`lessons`** — `{ _id, courseId, title, order, content, videoUrl, isFreePreview: bool }`.
|
|
52
|
+
Ordered lessons belonging to a course.
|
|
53
|
+
- **`enrollments`** — `{ _id, userId, courseId, stripeSessionId, enrolledAt }`.
|
|
54
|
+
Created by the Stripe webhook after a successful purchase. This document is the
|
|
55
|
+
access grant — the lesson player checks for it.
|
|
56
|
+
- **`progress`** — `{ _id, userId, courseId, lessonId, completedAt }`. One doc per
|
|
57
|
+
student per completed lesson; unique compound index on `(userId, lessonId)`.
|
|
58
|
+
A course's progress % = `completed lessons / total lessons`.
|
|
59
|
+
|
|
60
|
+
Add indexes: `courses.slug` (unique), `lessons.courseId+order`,
|
|
61
|
+
`enrollments.userId+courseId` (unique), `progress.userId+lessonId` (unique).
|
|
62
|
+
|
|
63
|
+
Access rule the whole platform hinges on: **a lesson is viewable if
|
|
64
|
+
`isFreePreview` OR an `enrollments` doc exists for `(userId, courseId)`.** Enforce
|
|
65
|
+
this on the server (in the lesson page + any lesson-content API), never only in
|
|
66
|
+
the UI.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## 3. How CloudGrid injects everything
|
|
71
|
+
|
|
72
|
+
You never provision infra or set connection strings by hand. Declared needs and
|
|
73
|
+
vault items are injected as environment variables at `grid dev` (local) and at
|
|
74
|
+
runtime (after `grid plug`).
|
|
75
|
+
|
|
76
|
+
- **Mongo** — `needs: { database: true }` → the grid injects
|
|
77
|
+
**`DATABASE_MONGODB_URL`** (plus the legacy **`MONGODB_URL`** alias). Read
|
|
78
|
+
`process.env.DATABASE_MONGODB_URL || process.env.MONGODB_URL` **lazily inside a
|
|
79
|
+
getter** in `lib/db.js`. A top-level read (`const uri = process.env…; if (!uri)
|
|
80
|
+
throw`) breaks `next build`, which imports the module for route analysis before
|
|
81
|
+
the grid injects the var. Never hardcode a URI; never commit a secret.
|
|
82
|
+
- **Secrets via the `vault:` block** — the block maps org vault items to env vars:
|
|
83
|
+
`STRIPE_KEY` ← `stripe-live-key`, `STRIPE_WEBHOOK_SECRET` ← `stripe-webhook-secret`,
|
|
84
|
+
`AUTH_PROVIDER_KEY` ← `auth-provider-key`. Set each vault item ONCE with
|
|
85
|
+
`grid secrets set <item>` (e.g. `grid secrets set stripe-live-key`); the platform
|
|
86
|
+
injects them as the named env vars. Read them lazily too (inside the Stripe/auth
|
|
87
|
+
client getters), not at module top level.
|
|
88
|
+
- **AI (only if you add tutoring/quiz-gen)** — `needs: { ai: true }` → injects
|
|
89
|
+
**`AI_GATEWAY_URL`**; call it via `@cloudgrid-io/ai`. Not enabled in this
|
|
90
|
+
blueprint; add the need if you want it.
|
|
91
|
+
|
|
92
|
+
Reserved env var names you must NOT set yourself: `PORT`, `NODE_ENV`,
|
|
93
|
+
`DATABASE_MONGODB_URL`/`MONGODB_URL`, `AI_GATEWAY_URL`, `CLOUDGRID_*`.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 4. Wiring auth + payments
|
|
98
|
+
|
|
99
|
+
### Auth (provider SDK)
|
|
100
|
+
Use a hosted auth provider SDK (e.g. Clerk or Auth0) rather than rolling your own.
|
|
101
|
+
|
|
102
|
+
1. Add the SDK to `package.json` (e.g. `@clerk/nextjs`).
|
|
103
|
+
2. Wrap `app/layout.js` in the provider; add `middleware.js` to protect
|
|
104
|
+
`/dashboard` and `/learn/*` routes.
|
|
105
|
+
3. The **publishable** key is a non-secret client env var → set it with
|
|
106
|
+
`grid env` (e.g. `grid env NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=…`). The **secret**
|
|
107
|
+
server key comes from the vault → `AUTH_PROVIDER_KEY` (mapped in `cloudgrid.yaml`),
|
|
108
|
+
read lazily in `lib/auth.js`.
|
|
109
|
+
4. `lib/auth.js` exposes `getUserId()` reading the provider's server session; every
|
|
110
|
+
protected route and the progress/enrollment APIs derive the user from it.
|
|
111
|
+
|
|
112
|
+
### Payments (Stripe)
|
|
113
|
+
1. `lib/stripe.js` builds the Stripe client lazily from `process.env.STRIPE_KEY`
|
|
114
|
+
(vault-injected).
|
|
115
|
+
2. **Checkout route** `app/api/checkout/route.js`: POST with a `courseId`, look up
|
|
116
|
+
the course price from Mongo, create a Stripe Checkout Session in `payment` mode
|
|
117
|
+
with `client_reference_id = userId` and `metadata.courseId`, and return
|
|
118
|
+
`session.url`. Never trust a price sent from the client — read it server-side.
|
|
119
|
+
3. **Webhook route** `app/api/webhooks/stripe/route.js`: POST endpoint Stripe calls.
|
|
120
|
+
Verify the signature with `STRIPE_WEBHOOK_SECRET`
|
|
121
|
+
(`stripe.webhooks.constructEvent(rawBody, sig, secret)`) — read the RAW request
|
|
122
|
+
body, do not JSON-parse first. On `checkout.session.completed`, upsert an
|
|
123
|
+
`enrollments` doc for `(client_reference_id, metadata.courseId)`. This webhook —
|
|
124
|
+
not the checkout redirect — is what actually grants access.
|
|
125
|
+
4. Register the webhook URL (`https://<live-url>/api/webhooks/stripe`) in the
|
|
126
|
+
Stripe dashboard after the first deploy, then set its signing secret into the
|
|
127
|
+
vault item `stripe-webhook-secret`.
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## 5. Deploy steps
|
|
132
|
+
|
|
133
|
+
A runtime deploy is **asynchronous** and requires the **local edition** (§6).
|
|
134
|
+
|
|
135
|
+
1. **`grid init`** an app named `course-platform`. `init` creates the entity +
|
|
136
|
+
`.cloudgrid/link.json` and writes a `cloudgrid.yaml` with an empty
|
|
137
|
+
`services: {}`. Run it FIRST — `plug` needs a linked directory.
|
|
138
|
+
2. **Fill** — replace the generated `cloudgrid.yaml` with the one in this template
|
|
139
|
+
(name + vault + `services.web` nextjs + `needs: { database: true }`), and write
|
|
140
|
+
the app under `services/web/` per the tree above.
|
|
141
|
+
3. **Set secrets** — `grid secrets set stripe-live-key`,
|
|
142
|
+
`grid secrets set stripe-webhook-secret`, `grid secrets set auth-provider-key`.
|
|
143
|
+
Set non-secret client config with `grid env` (e.g. the auth publishable key).
|
|
144
|
+
Do NOT set the DB vars — the grid injects them.
|
|
145
|
+
4. **`grid plug`** — builds + deploys `services/web/`. The first response is
|
|
146
|
+
`status: building`, NOT a live URL. Poll `grid status` (or the returned
|
|
147
|
+
poll_url) until it is live; surface a liveness signal while it builds, never a
|
|
148
|
+
bare silent wait. Only then return the live app URL.
|
|
149
|
+
5. **Wire the Stripe webhook** to the live URL (§4), then re-plug the SAME entity
|
|
150
|
+
to iterate — it updates the same URL.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## 6. Edition note
|
|
155
|
+
|
|
156
|
+
A course platform is a built + deployed **runtime** container. It requires the
|
|
157
|
+
**local edition** (Claude Desktop / Claude Code) or the CLI. On the **hosted**
|
|
158
|
+
edition (Claude Web / hosted MCP) you cannot build a runtime app — hosted is
|
|
159
|
+
inline-only and can only publish static pages. If you are on hosted, say so
|
|
160
|
+
plainly and stop the runtime path (a static course *landing* page is the only
|
|
161
|
+
thing hosted can ship).
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# course-platform template — blueprint (structure + cloudgrid.yaml)
|
|
2
|
+
|
|
3
|
+
A Teachable-style course platform: sell online courses, gate lessons behind a
|
|
4
|
+
Stripe purchase, and track each student's lesson progress — a persistent
|
|
5
|
+
Next.js + Mongo app with auth and payments. This is a **blueprint**: it ships the
|
|
6
|
+
correct `cloudgrid.yaml` and an `AGENTS.md` structure guide (file tree, Mongo
|
|
7
|
+
collections, CloudGrid env/vault wiring, auth + Stripe routes, deploy steps), not
|
|
8
|
+
runnable app code. Adapt the structure and build the app under `services/web/`.
|
|
9
|
+
|
|
10
|
+
## What's here
|
|
11
|
+
|
|
12
|
+
- **`cloudgrid.yaml`** — full-annotated reference with only the active fields
|
|
13
|
+
uncommented: `name`, a `vault:` block (`STRIPE_KEY`, `STRIPE_WEBHOOK_SECRET`,
|
|
14
|
+
`AUTH_PROVIDER_KEY`), `services.web` (type: nextjs, path: /), and
|
|
15
|
+
`needs: { database: true }`. Copy it as-is.
|
|
16
|
+
- **`AGENTS.md`** — the structure guide. Read it before building: it is the
|
|
17
|
+
CloudGrid-specific spec for the file tree, collections, secret injection, and
|
|
18
|
+
the async runtime deploy.
|
|
19
|
+
|
|
20
|
+
## Blueprint: structure + cloudgrid.yaml, adapt and build
|
|
21
|
+
|
|
22
|
+
Read `AGENTS.md`, then build the app following it — put the code under
|
|
23
|
+
`services/web/`, read `DATABASE_MONGODB_URL` (legacy `MONGODB_URL` fallback) and
|
|
24
|
+
the vault-injected `STRIPE_KEY` / `AUTH_PROVIDER_KEY` lazily inside getters,
|
|
25
|
+
declare `needs: { database: true }`, and deploy with `grid plug` (async — poll to
|
|
26
|
+
a live URL; local edition only).
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# ============================================================================
|
|
2
|
+
# cloudgrid.yaml — Complete Example
|
|
3
|
+
# ============================================================================
|
|
4
|
+
#
|
|
5
|
+
# This file shows EVERY field the platform supports, with comments explaining
|
|
6
|
+
# each one. It is a reference — no real project would use all of these at once.
|
|
7
|
+
#
|
|
8
|
+
# STANDARD: every CloudGrid template ships its cloudgrid.yaml in THIS full form.
|
|
9
|
+
# Uncomment ONLY the fields the archetype needs (always: name + services; plus
|
|
10
|
+
# needs: for runtime apps). Leave everything else commented. Comments are
|
|
11
|
+
# ignored by the parser, so the file deploys to exactly the active fields.
|
|
12
|
+
#
|
|
13
|
+
# Only two fields are required: name and services. Everything else is optional.
|
|
14
|
+
# Full docs: docs/cloudgrid-yaml-reference.md
|
|
15
|
+
# ============================================================================
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# ─── IDENTITY ───────────────────────────────────────────────────────────────
|
|
19
|
+
|
|
20
|
+
# Entity slug (REQUIRED). 2-42 chars, lowercase alphanumeric + hyphens.
|
|
21
|
+
# Must start and end with a letter or digit.
|
|
22
|
+
# Becomes part of your public URL: <name>-<4hex>.<org>.cloudgrid.io
|
|
23
|
+
name: course-platform
|
|
24
|
+
|
|
25
|
+
# One-line summary. Max 280 chars. If omitted, Grid Brain auto-generates one.
|
|
26
|
+
# description: Order processing API for the e-commerce platform
|
|
27
|
+
|
|
28
|
+
# Single emoji or short text shown as the entity icon. Max 64 chars.
|
|
29
|
+
# icon: "📦"
|
|
30
|
+
|
|
31
|
+
# Entity type: 'app' (default) or 'agent'. An agent is an app with an agent: block.
|
|
32
|
+
# kind: app
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# ─── NETWORKING ─────────────────────────────────────────────────────────────
|
|
36
|
+
|
|
37
|
+
# Whether this entity serves public HTTP traffic.
|
|
38
|
+
# true = public URL + Ingress (default). false = internal only.
|
|
39
|
+
# expose: true
|
|
40
|
+
|
|
41
|
+
# Additional domain names this entity serves on (the platform URL is always active).
|
|
42
|
+
# custom_domains:
|
|
43
|
+
# - orders.example.com
|
|
44
|
+
# - shop.example.com
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# ─── HEALTH PROBE (entity-level override) ──────────────────────────────────
|
|
48
|
+
|
|
49
|
+
# Override the default health check for the entire entity.
|
|
50
|
+
# probe:
|
|
51
|
+
# path: /healthz # HTTP path to probe (default: /).
|
|
52
|
+
# expected: "<500" # '<500' (default), '200', '2xx'.
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
# ─── DEPLOY NOTIFICATIONS ──────────────────────────────────────────────────
|
|
56
|
+
|
|
57
|
+
# Slack notification to the org's default channel on deploy failure.
|
|
58
|
+
# true = notify (default), false = silent.
|
|
59
|
+
# notify: true
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# ─── SCALING ────────────────────────────────────────────────────────────────
|
|
63
|
+
|
|
64
|
+
# Replica scaling intent.
|
|
65
|
+
# 'auto' — platform decides from the grid tier (default).
|
|
66
|
+
# 'alert' — single-replica, emit a SPOF warning at plug time.
|
|
67
|
+
# 1-10 — explicit replica count, clamped to the grid max.
|
|
68
|
+
# scale: auto
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
# ─── INFRASTRUCTURE NEEDS ──────────────────────────────────────────────────
|
|
72
|
+
#
|
|
73
|
+
# Declare infrastructure; the platform provisions it and injects connection
|
|
74
|
+
# details as env vars. Nine needs: database, cache, kv, queue, pubsub, vector,
|
|
75
|
+
# object_storage, disk, ai. Simplest form is `true`.
|
|
76
|
+
#
|
|
77
|
+
# needs:
|
|
78
|
+
# # database — MongoDB. Injects DATABASE_MONGODB_URL (+ legacy MONGODB_URL).
|
|
79
|
+
# # true | pool | dedicated | { tier: external, secret: MY_DB }
|
|
80
|
+
# database: true
|
|
81
|
+
# # cache — Redis, LRU eviction (derived data). Injects CACHE_REDIS_URL (+ REDIS_URL).
|
|
82
|
+
# # true | redis | { engine: external, secret: MY_REDIS_URL }
|
|
83
|
+
# cache: true
|
|
84
|
+
# # kv — Redis, no eviction (durable: flags, idempotency). Injects KV_REDIS_URL.
|
|
85
|
+
# kv: true
|
|
86
|
+
# # queue — Redis job-queue substrate (BullMQ). Injects QUEUE_REDIS_URL.
|
|
87
|
+
# queue: true
|
|
88
|
+
# # pubsub — Redis broadcast pub/sub. Injects PUBSUB_REDIS_URL.
|
|
89
|
+
# pubsub: true
|
|
90
|
+
# # vector — pgvector on Postgres. Injects VECTOR_PGVECTOR_URL (+ PGVECTOR_URL).
|
|
91
|
+
# # true | pgvector | { engine: pgvector, dim: 1536 }
|
|
92
|
+
# vector: pgvector
|
|
93
|
+
# # object_storage — GCS bucket. Injects OBJECT_STORAGE_GCS_BUCKET, _GCS_REGION.
|
|
94
|
+
# # true | { size: 10Gi }
|
|
95
|
+
# object_storage: true
|
|
96
|
+
# # disk — persistent FS mount (PVC). Injects DISK_PATH. Pins to 1 replica.
|
|
97
|
+
# # true | { size: 1Gi, mount: /var/data } (forbidden: /proc /sys /dev)
|
|
98
|
+
# disk: true
|
|
99
|
+
# # ai — AI Gateway via @cloudgrid-io/ai. Injects AI_GATEWAY_URL. true | false.
|
|
100
|
+
# ai: true
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
# ─── INTER-ENTITY COMMUNICATION ────────────────────────────────────────────
|
|
104
|
+
|
|
105
|
+
# Entities this app calls (outbound). Service-account token injected per pair.
|
|
106
|
+
# calls:
|
|
107
|
+
# - org:atomic/billing-api
|
|
108
|
+
|
|
109
|
+
# Inbound caller policy — who can call YOUR entity.
|
|
110
|
+
# callers:
|
|
111
|
+
# policy: auto # 'auto' | 'manual' (default).
|
|
112
|
+
# scope: org # 'org' (default) | 'space' | 'explicit'.
|
|
113
|
+
# fallback: deny # 'deny' (default) | 'warn'.
|
|
114
|
+
# # allowed_apps: # required only when scope: explicit
|
|
115
|
+
# # - org:atomic/frontend
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
# ─── VAULT ──────────────────────────────────────────────────────────────────
|
|
119
|
+
|
|
120
|
+
# Map org vault items to env vars. Keys UPPER_SNAKE_CASE; values = vault item keys.
|
|
121
|
+
# Stripe secret key for the checkout + webhook routes (course purchases). Set the
|
|
122
|
+
# vault item once (`grid secrets set stripe-live-key`) and the platform injects it
|
|
123
|
+
# as STRIPE_KEY. STRIPE_WEBHOOK_SECRET verifies incoming checkout webhooks.
|
|
124
|
+
# AUTH_PROVIDER_KEY is the server-side secret for your auth provider (Clerk/Auth0).
|
|
125
|
+
vault:
|
|
126
|
+
STRIPE_KEY: stripe-live-key
|
|
127
|
+
STRIPE_WEBHOOK_SECRET: stripe-webhook-secret
|
|
128
|
+
AUTH_PROVIDER_KEY: auth-provider-key
|
|
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
|
+
|
|
227
|
+
needs:
|
|
228
|
+
database: true
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
# ============================================================================
|
|
232
|
+
# NOTES
|
|
233
|
+
# - NOT here: org:/entity_id: (→ .cloudgrid/link.json), secrets (→ grid secrets set),
|
|
234
|
+
# Dockerfile (platform generates from services.*.type).
|
|
235
|
+
# - Deploy: grid plug | Local with grid resources: grid dev
|
|
236
|
+
# - Full reference: docs/cloudgrid-yaml-reference.md | CLI: docs/cli-reference.md
|
|
237
|
+
# ============================================================================
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Template: course-platform (blueprint — Next.js + Mongo + auth + Stripe)
|
|
2
|
+
|
|
3
|
+
A Teachable-style course platform: sell online courses, gate lessons behind a
|
|
4
|
+
Stripe purchase, and track per-student lesson progress. Persistent
|
|
5
|
+
Next.js + Mongo app with auth and payments.
|
|
6
|
+
|
|
7
|
+
**This is a blueprint, not app code.** It ships the correct `cloudgrid.yaml` and
|
|
8
|
+
an `AGENTS.md` structure guide. Read `AGENTS.md`, then build the app under
|
|
9
|
+
`services/web/` following it. Fetch the guide with
|
|
10
|
+
`gridctl_fetch("template", "course-platform")`.
|
|
11
|
+
|
|
12
|
+
**Key rules:**
|
|
13
|
+
|
|
14
|
+
1. **Service code MUST live under `services/web/`**, not the repo/template root.
|
|
15
|
+
`path: /` in `cloudgrid.yaml` is the URL mount, NOT the filesystem path.
|
|
16
|
+
2. **Read injected vars LAZILY (inside getters), never at module top level.** The
|
|
17
|
+
grid injects `DATABASE_MONGODB_URL` (legacy `MONGODB_URL` fallback) from
|
|
18
|
+
`needs: { database: true }`, and `STRIPE_KEY` / `STRIPE_WEBHOOK_SECRET` /
|
|
19
|
+
`AUTH_PROVIDER_KEY` from the `vault:` block. A top-level read fails `next build`.
|
|
20
|
+
3. **Declare the datastore with `needs: { database: true }`** — the canonical
|
|
21
|
+
shape. `requires:` is the deprecated v1 alias; never set `needs:` and
|
|
22
|
+
`requires:` together (the validator rejects the combination).
|
|
23
|
+
4. **Secrets via the `vault:` block** — set each vault item once with
|
|
24
|
+
`grid secrets set <item>`; the platform injects it as the named env var. The
|
|
25
|
+
auth publishable (non-secret) key is a `grid env` var, not a vault item.
|
|
26
|
+
5. **Runtime deploy is async, local edition only.** `grid plug` returns
|
|
27
|
+
`status: building`; poll to a live URL. Register the Stripe webhook to the live
|
|
28
|
+
URL after the first deploy.
|
|
29
|
+
|
|
30
|
+
## Domain (Mongo collections)
|
|
31
|
+
|
|
32
|
+
- `courses` (slug, title, priceCents, published) — sellable courses
|
|
33
|
+
- `lessons` (courseId, order, content, isFreePreview) — ordered lessons
|
|
34
|
+
- `enrollments` (userId, courseId, stripeSessionId) — access grant, created by the Stripe webhook
|
|
35
|
+
- `progress` (userId, courseId, lessonId, completedAt) — per-lesson completion
|
|
36
|
+
|
|
37
|
+
Access rule: a lesson is viewable if `isFreePreview` OR an `enrollments` doc
|
|
38
|
+
exists for `(userId, courseId)`. Enforce on the server, not just in the UI.
|
|
39
|
+
|
|
40
|
+
## cloudgrid.yaml
|
|
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: course-platform
|
|
47
|
+
vault:
|
|
48
|
+
STRIPE_KEY: stripe-live-key
|
|
49
|
+
STRIPE_WEBHOOK_SECRET: stripe-webhook-secret
|
|
50
|
+
AUTH_PROVIDER_KEY: auth-provider-key
|
|
51
|
+
services:
|
|
52
|
+
web:
|
|
53
|
+
type: nextjs
|
|
54
|
+
path: /
|
|
55
|
+
needs:
|
|
56
|
+
database: true
|
|
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
|
+
> org secrets (`stripe-live-key`, `stripe-webhook-secret`, `auth-provider-key`) to
|
|
62
|
+
> env vars for the checkout/webhook and auth routes. See the capability-map for
|
|
63
|
+
> the full injection table.
|
|
64
|
+
|
|
65
|
+
## Build it
|
|
66
|
+
|
|
67
|
+
Read `AGENTS.md` for the full file tree, collection fields, env/vault wiring, auth
|
|
68
|
+
+ Stripe route contracts, and deploy steps. Then scaffold (`grid init`), write the
|
|
69
|
+
app under `services/web/`, set secrets (`grid secrets set …`), and `grid plug`
|
|
70
|
+
(async — poll to a live URL). Re-plug the same entity to iterate.
|