@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.
- package/package.json +1 -1
- package/src/corpus/capability-map.md +82 -2
- package/src/corpus/examples/crm/index.md +273 -0
- package/src/corpus/examples/kanban/index.md +256 -0
- package/src/corpus/templates/_cloudgrid.yaml.reference +228 -0
- package/src/corpus/templates/admin-dashboard/README.md +75 -0
- package/src/corpus/templates/admin-dashboard/cloudgrid.yaml +233 -0
- package/src/corpus/templates/admin-dashboard/index.md +81 -0
- package/src/corpus/templates/admin-dashboard/services/web/app/api/orders/route.js +64 -0
- package/src/corpus/templates/admin-dashboard/services/web/app/api/users/route.js +63 -0
- package/src/corpus/templates/admin-dashboard/services/web/app/layout.js +39 -0
- package/src/corpus/templates/admin-dashboard/services/web/app/page.js +73 -0
- package/src/corpus/templates/admin-dashboard/services/web/app/resource-table.js +94 -0
- package/src/corpus/templates/admin-dashboard/services/web/lib/db.js +32 -0
- package/src/corpus/templates/admin-dashboard/services/web/package.json +16 -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/README.md +28 -0
- package/src/corpus/templates/api-docs/cloudgrid.yaml +228 -0
- package/src/corpus/templates/api-docs/index.html +136 -0
- package/src/corpus/templates/api-docs/index.md +28 -0
- 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/README.md +27 -0
- package/src/corpus/templates/changelog/cloudgrid.yaml +228 -0
- package/src/corpus/templates/changelog/index.html +80 -0
- package/src/corpus/templates/changelog/index.md +28 -0
- 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/README.md +72 -0
- package/src/corpus/templates/crm/cloudgrid.yaml +233 -0
- package/src/corpus/templates/crm/index.md +71 -0
- package/src/corpus/templates/crm/services/web/app/api/contacts/route.js +80 -0
- package/src/corpus/templates/crm/services/web/app/contact-manager.js +102 -0
- package/src/corpus/templates/crm/services/web/app/layout.js +35 -0
- package/src/corpus/templates/crm/services/web/app/page.js +34 -0
- package/src/corpus/templates/crm/services/web/lib/db.js +32 -0
- package/src/corpus/templates/crm/services/web/package.json +16 -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/README.md +28 -0
- package/src/corpus/templates/docs-site/cloudgrid.yaml +228 -0
- package/src/corpus/templates/docs-site/index.html +122 -0
- package/src/corpus/templates/docs-site/index.md +28 -0
- 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/README.md +72 -0
- package/src/corpus/templates/kanban/cloudgrid.yaml +233 -0
- package/src/corpus/templates/kanban/index.md +71 -0
- package/src/corpus/templates/kanban/services/web/app/api/cards/route.js +70 -0
- package/src/corpus/templates/kanban/services/web/app/board.js +93 -0
- package/src/corpus/templates/kanban/services/web/app/layout.js +37 -0
- package/src/corpus/templates/kanban/services/web/app/page.js +32 -0
- package/src/corpus/templates/kanban/services/web/lib/db.js +32 -0
- package/src/corpus/templates/kanban/services/web/package.json +16 -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/README.md +29 -0
- package/src/corpus/templates/portfolio/cloudgrid.yaml +228 -0
- package/src/corpus/templates/portfolio/index.html +126 -0
- package/src/corpus/templates/portfolio/index.md +28 -0
- 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/README.md +30 -0
- package/src/corpus/templates/saas-marketing/cloudgrid.yaml +228 -0
- package/src/corpus/templates/saas-marketing/index.html +212 -0
- package/src/corpus/templates/saas-marketing/index.md +28 -0
- package/src/corpus/templates/status-page/README.md +28 -0
- package/src/corpus/templates/status-page/cloudgrid.yaml +228 -0
- package/src/corpus/templates/status-page/index.html +117 -0
- package/src/corpus/templates/status-page/index.md +28 -0
- 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/README.md +72 -0
- package/src/corpus/templates/task-manager/cloudgrid.yaml +233 -0
- package/src/corpus/templates/task-manager/index.md +71 -0
- package/src/corpus/templates/task-manager/services/web/app/api/tasks/route.js +77 -0
- package/src/corpus/templates/task-manager/services/web/app/layout.js +39 -0
- package/src/corpus/templates/task-manager/services/web/app/page.js +33 -0
- package/src/corpus/templates/task-manager/services/web/app/task-list.js +110 -0
- package/src/corpus/templates/task-manager/services/web/lib/db.js +32 -0
- package/src/corpus/templates/task-manager/services/web/package.json +16 -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/README.md +38 -0
- package/src/corpus/templates/waitlist/cloudgrid.yaml +228 -0
- package/src/corpus/templates/waitlist/index.html +69 -0
- package/src/corpus/templates/waitlist/index.md +39 -0
- package/src/corpus/templates/web-app/cloudgrid.yaml +228 -4
- package/src/corpus/templates/web-app/index.md +3 -5
- package/src/corpus/workflows/admin-dashboard.md +102 -0
- 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/api-docs.md +36 -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/changelog.md +33 -0
- package/src/corpus/workflows/company-website.md +46 -0
- package/src/corpus/workflows/course-platform.md +126 -0
- package/src/corpus/workflows/crm.md +101 -0
- package/src/corpus/workflows/directory.md +101 -0
- package/src/corpus/workflows/docs-site.md +35 -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/kanban.md +102 -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/portfolio.md +35 -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/saas-marketing.md +37 -0
- package/src/corpus/workflows/status-page.md +35 -0
- package/src/corpus/workflows/subscription-management.md +141 -0
- package/src/corpus/workflows/task-manager.md +101 -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
- package/src/corpus/workflows/waitlist.md +42 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# ============================================================================
|
|
2
|
+
# cloudgrid.yaml — Complete Example
|
|
3
|
+
# ============================================================================
|
|
4
|
+
#
|
|
5
|
+
# This file shows EVERY field the platform supports, with comments explaining
|
|
6
|
+
# each one. It is a reference — no real project would use all of these at once.
|
|
7
|
+
#
|
|
8
|
+
# STANDARD: every CloudGrid template ships its cloudgrid.yaml in THIS full form.
|
|
9
|
+
# Uncomment ONLY the fields the archetype needs (always: name + services; plus
|
|
10
|
+
# needs: for runtime apps). Leave everything else commented. Comments are
|
|
11
|
+
# ignored by the parser, so the file deploys to exactly the active fields.
|
|
12
|
+
#
|
|
13
|
+
# Only two fields are required: name and services. Everything else is optional.
|
|
14
|
+
# Full docs: docs/cloudgrid-yaml-reference.md
|
|
15
|
+
# ============================================================================
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# ─── IDENTITY ───────────────────────────────────────────────────────────────
|
|
19
|
+
|
|
20
|
+
# Entity slug (REQUIRED). 2-42 chars, lowercase alphanumeric + hyphens.
|
|
21
|
+
# Must start and end with a letter or digit.
|
|
22
|
+
# Becomes part of your public URL: <name>-<4hex>.<org>.cloudgrid.io
|
|
23
|
+
name: appointment-booking
|
|
24
|
+
|
|
25
|
+
# One-line summary. Max 280 chars. If omitted, Grid Brain auto-generates one.
|
|
26
|
+
# description: Order processing API for the e-commerce platform
|
|
27
|
+
|
|
28
|
+
# Single emoji or short text shown as the entity icon. Max 64 chars.
|
|
29
|
+
# icon: "📦"
|
|
30
|
+
|
|
31
|
+
# Entity type: 'app' (default) or 'agent'. An agent is an app with an agent: block.
|
|
32
|
+
# kind: app
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# ─── NETWORKING ─────────────────────────────────────────────────────────────
|
|
36
|
+
|
|
37
|
+
# Whether this entity serves public HTTP traffic.
|
|
38
|
+
# true = public URL + Ingress (default). false = internal only.
|
|
39
|
+
# expose: true
|
|
40
|
+
|
|
41
|
+
# Additional domain names this entity serves on (the platform URL is always active).
|
|
42
|
+
# custom_domains:
|
|
43
|
+
# - orders.example.com
|
|
44
|
+
# - shop.example.com
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# ─── HEALTH PROBE (entity-level override) ──────────────────────────────────
|
|
48
|
+
|
|
49
|
+
# Override the default health check for the entire entity.
|
|
50
|
+
# probe:
|
|
51
|
+
# path: /healthz # HTTP path to probe (default: /).
|
|
52
|
+
# expected: "<500" # '<500' (default), '200', '2xx'.
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
# ─── DEPLOY NOTIFICATIONS ──────────────────────────────────────────────────
|
|
56
|
+
|
|
57
|
+
# Slack notification to the org's default channel on deploy failure.
|
|
58
|
+
# true = notify (default), false = silent.
|
|
59
|
+
# notify: true
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# ─── SCALING ────────────────────────────────────────────────────────────────
|
|
63
|
+
|
|
64
|
+
# Replica scaling intent.
|
|
65
|
+
# 'auto' — platform decides from the grid tier (default).
|
|
66
|
+
# 'alert' — single-replica, emit a SPOF warning at plug time.
|
|
67
|
+
# 1-10 — explicit replica count, clamped to the grid max.
|
|
68
|
+
# scale: auto
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
# ─── INFRASTRUCTURE NEEDS ──────────────────────────────────────────────────
|
|
72
|
+
#
|
|
73
|
+
# Declare infrastructure; the platform provisions it and injects connection
|
|
74
|
+
# details as env vars. Nine needs: database, cache, kv, queue, pubsub, vector,
|
|
75
|
+
# object_storage, disk, ai. Simplest form is `true`.
|
|
76
|
+
#
|
|
77
|
+
# needs:
|
|
78
|
+
# # database — MongoDB. Injects DATABASE_MONGODB_URL (+ legacy MONGODB_URL).
|
|
79
|
+
# # true | pool | dedicated | { tier: external, secret: MY_DB }
|
|
80
|
+
# database: true
|
|
81
|
+
# # cache — Redis, LRU eviction (derived data). Injects CACHE_REDIS_URL (+ REDIS_URL).
|
|
82
|
+
# # true | redis | { engine: external, secret: MY_REDIS_URL }
|
|
83
|
+
# cache: true
|
|
84
|
+
# # kv — Redis, no eviction (durable: flags, idempotency). Injects KV_REDIS_URL.
|
|
85
|
+
# kv: true
|
|
86
|
+
# # queue — Redis job-queue substrate (BullMQ). Injects QUEUE_REDIS_URL.
|
|
87
|
+
# queue: true
|
|
88
|
+
# # pubsub — Redis broadcast pub/sub. Injects PUBSUB_REDIS_URL.
|
|
89
|
+
# pubsub: true
|
|
90
|
+
# # vector — pgvector on Postgres. Injects VECTOR_PGVECTOR_URL (+ PGVECTOR_URL).
|
|
91
|
+
# # true | pgvector | { engine: pgvector, dim: 1536 }
|
|
92
|
+
# vector: pgvector
|
|
93
|
+
# # object_storage — GCS bucket. Injects OBJECT_STORAGE_GCS_BUCKET, _GCS_REGION.
|
|
94
|
+
# # true | { size: 10Gi }
|
|
95
|
+
# object_storage: true
|
|
96
|
+
# # disk — persistent FS mount (PVC). Injects DISK_PATH. Pins to 1 replica.
|
|
97
|
+
# # true | { size: 1Gi, mount: /var/data } (forbidden: /proc /sys /dev)
|
|
98
|
+
# disk: true
|
|
99
|
+
# # ai — AI Gateway via @cloudgrid-io/ai. Injects AI_GATEWAY_URL. true | false.
|
|
100
|
+
# ai: true
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
# ─── INTER-ENTITY COMMUNICATION ────────────────────────────────────────────
|
|
104
|
+
|
|
105
|
+
# Entities this app calls (outbound). Service-account token injected per pair.
|
|
106
|
+
# calls:
|
|
107
|
+
# - org:atomic/billing-api
|
|
108
|
+
|
|
109
|
+
# Inbound caller policy — who can call YOUR entity.
|
|
110
|
+
# callers:
|
|
111
|
+
# policy: auto # 'auto' | 'manual' (default).
|
|
112
|
+
# scope: org # 'org' (default) | 'space' | 'explicit'.
|
|
113
|
+
# fallback: deny # 'deny' (default) | 'warn'.
|
|
114
|
+
# # allowed_apps: # required only when scope: explicit
|
|
115
|
+
# # - org:atomic/frontend
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
# ─── VAULT ──────────────────────────────────────────────────────────────────
|
|
119
|
+
|
|
120
|
+
# Map org vault items to env vars. Keys UPPER_SNAKE_CASE; values = vault item keys.
|
|
121
|
+
# Auth (so providers/clients own bookings) and optional deposit payments need
|
|
122
|
+
# secrets injected as env vars — this is the CloudGrid-correct way. Set each
|
|
123
|
+
# vault item once (grid secrets set), then the deployer injects it as the named
|
|
124
|
+
# env var at runtime and under `grid dev`. Read them LAZILY, never top-level.
|
|
125
|
+
vault:
|
|
126
|
+
AUTH_PROVIDER_KEY: auth-provider-key # auth SDK server key (e.g. Clerk secret / Auth0 client secret)
|
|
127
|
+
STRIPE_KEY: stripe-live-key # Stripe secret key — optional booking deposits / prepayment
|
|
128
|
+
STRIPE_WEBHOOK_SECRET: stripe-webhook-secret # verifies Stripe webhook signatures (deposit confirmation)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
# ─── CONNECTORS AND HOOKS ──────────────────────────────────────────────────
|
|
132
|
+
|
|
133
|
+
# connectors:
|
|
134
|
+
# - id: team-slack
|
|
135
|
+
# target: org # 'system' | 'org'.
|
|
136
|
+
# channel: "#deploys"
|
|
137
|
+
# hooks:
|
|
138
|
+
# - on: deploy.failed # release.published | deploy.failed | feedback.received | entity.created
|
|
139
|
+
# via: team-slack
|
|
140
|
+
# template: "Deploy failed for {entity_name}: {error}"
|
|
141
|
+
# channel: "#alerts"
|
|
142
|
+
# triggers:
|
|
143
|
+
# - from: team-slack
|
|
144
|
+
# event: message
|
|
145
|
+
# channel: "#support"
|
|
146
|
+
# route: /webhooks/slack
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
# ─── LOCAL DEVELOPMENT ──────────────────────────────────────────────────────
|
|
150
|
+
|
|
151
|
+
# Config for `grid dev`. Redact fields in dev data snapshots.
|
|
152
|
+
# dev:
|
|
153
|
+
# snapshot:
|
|
154
|
+
# mask:
|
|
155
|
+
# - users.email
|
|
156
|
+
# - users.phone
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# ─── AGENT METADATA ────────────────────────────────────────────────────────
|
|
160
|
+
|
|
161
|
+
# An agent is an app with kind: agent (above) and an agent: block.
|
|
162
|
+
# agent:
|
|
163
|
+
# purpose: Sync customer data from external CRM every night
|
|
164
|
+
# schedule: "0 2 * * *"
|
|
165
|
+
# trigger: webhook
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
# ─── PRIVATE RESOURCE AUTO-DEPENDENCIES ────────────────────────────────────
|
|
169
|
+
|
|
170
|
+
# When true (default), private resources are auto-injected as depends_on.
|
|
171
|
+
# auto_depends_on_private_requires: true
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
# ─── SERVICES (REQUIRED) ───────────────────────────────────────────────────
|
|
175
|
+
#
|
|
176
|
+
# At least one service is required. Key = service name (slug rules).
|
|
177
|
+
# Types: node, nextjs, python, static, cron.
|
|
178
|
+
#
|
|
179
|
+
services:
|
|
180
|
+
web:
|
|
181
|
+
# type (REQUIRED): node | nextjs | python | static | cron
|
|
182
|
+
type: nextjs
|
|
183
|
+
# HTTP route: '/' | '/api' | false (internal) | omitted (=false + warning).
|
|
184
|
+
# Only one service per entity can claim '/'.
|
|
185
|
+
path: /
|
|
186
|
+
# Container port (default 8080; read process.env.PORT). Not for cron.
|
|
187
|
+
# port: 3000
|
|
188
|
+
# nextjs only: base_image: distroless (default) | alpine
|
|
189
|
+
# base_image: distroless
|
|
190
|
+
# node only: lang: javascript (default) | typescript
|
|
191
|
+
# lang: typescript
|
|
192
|
+
# Custom source location (default services/<name>/). '.' = project root.
|
|
193
|
+
# source:
|
|
194
|
+
# path: src/worker
|
|
195
|
+
# Health probe: false/omitted (TCP) | true (/health) | "/path" | {path,expected}
|
|
196
|
+
# health:
|
|
197
|
+
# path: /api/health
|
|
198
|
+
# expected: "200"
|
|
199
|
+
# Static runtime env vars (strings). Reserved: PORT, APP_NAME, SERVICE_NAME,
|
|
200
|
+
# NODE_ENV, MONGODB_URL, REDIS_URL, AI_GATEWAY_URL, N8N_WEBHOOK_URL, CLOUDGRID_*.
|
|
201
|
+
# env:
|
|
202
|
+
# LOG_LEVEL: info
|
|
203
|
+
# Sibling services/private resources that must be Ready first (no cron, no cycles).
|
|
204
|
+
# depends_on:
|
|
205
|
+
# - worker
|
|
206
|
+
# Per-service needs override (merges with app-level needs).
|
|
207
|
+
# needs:
|
|
208
|
+
# queue: true
|
|
209
|
+
# Static-only build step:
|
|
210
|
+
# build:
|
|
211
|
+
# command: npm run build
|
|
212
|
+
# output: dist
|
|
213
|
+
# env:
|
|
214
|
+
# VITE_API_URL: https://api.example.com
|
|
215
|
+
# node_version: "22" # static build step: '18'|'20'|'22'|'24' (quoted)
|
|
216
|
+
# Cron-only: schedule (REQUIRED), timezone (UTC|EST|PST), run (job | https URL)
|
|
217
|
+
# schedule: "0 9 * * 1"
|
|
218
|
+
# timezone: UTC
|
|
219
|
+
# run: job
|
|
220
|
+
# Verbose per-service persistence (prefer needs.disk):
|
|
221
|
+
# persist:
|
|
222
|
+
# - name: scratch
|
|
223
|
+
# path: /tmp/scratch
|
|
224
|
+
# size: 500Mi
|
|
225
|
+
|
|
226
|
+
# ── INTENDED cron service — appointment reminders (NOT YET DEPLOYABLE) ──
|
|
227
|
+
# This design wants a scheduled job to send reminders for upcoming
|
|
228
|
+
# appointments (e.g. "24h before"). The shape below is the intended cron
|
|
229
|
+
# service. Cron deploy is a PENDING platform issue (#1543) — leave this
|
|
230
|
+
# COMMENTED until cron ships; uncommenting it today will not deploy. See
|
|
231
|
+
# AGENTS.md § "Reminders (cron — PENDING #1543)" for the intended behaviour.
|
|
232
|
+
# reminders:
|
|
233
|
+
# type: cron
|
|
234
|
+
# schedule: "*/15 * * * *" # every 15 min: find appts entering the reminder window
|
|
235
|
+
# timezone: UTC
|
|
236
|
+
# run: job # runs services/reminders/ as a one-shot job per tick
|
|
237
|
+
# # Inherits app-level needs (database) + vault (for the notification provider key).
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
needs:
|
|
241
|
+
database: true
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
# ============================================================================
|
|
245
|
+
# NOTES
|
|
246
|
+
# - NOT here: org:/entity_id: (→ .cloudgrid/link.json), secrets (→ grid secrets set),
|
|
247
|
+
# Dockerfile (platform generates from services.*.type).
|
|
248
|
+
# - Deploy: grid plug | Local with grid resources: grid dev
|
|
249
|
+
# - Full reference: docs/cloudgrid-yaml-reference.md | CLI: docs/cli-reference.md
|
|
250
|
+
# ============================================================================
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Template: appointment-booking (BLUEPRINT — Next.js + auth + Mongo, optional Stripe)
|
|
2
|
+
|
|
3
|
+
An appointment / clinic / salon booking app. **Blueprint, not finished code**:
|
|
4
|
+
it ships the `cloudgrid.yaml` and a structure guide (`AGENTS.md`) so an agent can
|
|
5
|
+
build it correctly on CloudGrid — a Next.js app where a business defines
|
|
6
|
+
providers and bookable services, publishes availability, and clients book an open
|
|
7
|
+
slot, with auth so a provider owns their calendar, optional Stripe deposits, and
|
|
8
|
+
grid-shared Mongo. Read `AGENTS.md`, build the app under `services/web/`, adapt
|
|
9
|
+
the providers/services/slot rules, then deploy (async — poll to a live URL).
|
|
10
|
+
Local edition only.
|
|
11
|
+
|
|
12
|
+
**Fetch the bundle:**
|
|
13
|
+
- `gridctl_fetch("template", "appointment-booking")` — this blueprint (`cloudgrid.yaml` + `AGENTS.md`).
|
|
14
|
+
- `gridctl_fetch("template", "app-with-data")` — the proven Next.js + Mongo shape to extend (lazy db client, App-Router API).
|
|
15
|
+
|
|
16
|
+
**Key rules:**
|
|
17
|
+
|
|
18
|
+
1. **Blueprint — read `AGENTS.md` first.** It has the file tree, the Mongo
|
|
19
|
+
collections (`providers`, `services`, `availability`, `appointments`), the
|
|
20
|
+
slot-computation + anti-double-booking rules, the CloudGrid injection table,
|
|
21
|
+
and the auth + Stripe wiring. Build following it; do not invent structure.
|
|
22
|
+
2. **App code MUST live under `services/web/`.** `path: /` is the URL mount, NOT
|
|
23
|
+
the filesystem path. Root files fail with `Service directory not found`.
|
|
24
|
+
3. **Mongo via `needs:{database:true}`** → the grid injects
|
|
25
|
+
`DATABASE_MONGODB_URL` (legacy `MONGODB_URL` fallback). Read it LAZILY inside
|
|
26
|
+
the getter, never at module top level (top-level read fails `next build`).
|
|
27
|
+
4. **Secrets via the `vault:` block** → env vars. `AUTH_PROVIDER_KEY` (and, for
|
|
28
|
+
deposits, `STRIPE_KEY` / `STRIPE_WEBHOOK_SECRET`) map to vault items; set them
|
|
29
|
+
with `gridctl_secrets`, and the deployer injects them at runtime. Read lazily;
|
|
30
|
+
do not commit keys or put secrets in `services.web.env`.
|
|
31
|
+
5. **No double-booking.** `appointments` is the source of truth for "taken";
|
|
32
|
+
compute open slots as availability minus booked, re-check at write time, and
|
|
33
|
+
guard the insert with a partial unique index on `{ providerId, startAt }`.
|
|
34
|
+
6. **Never set `needs:` and `requires:` together** — `requires:` is the
|
|
35
|
+
deprecated v1 alias.
|
|
36
|
+
7. **Reminders (cron) are designed but PENDING platform issue #1543** — keep the
|
|
37
|
+
`reminders` cron service COMMENTED in `cloudgrid.yaml`; it is not yet
|
|
38
|
+
deployable. See AGENTS.md § 7.
|
|
39
|
+
|
|
40
|
+
## cloudgrid.yaml (active fields)
|
|
41
|
+
|
|
42
|
+
```yaml
|
|
43
|
+
# On disk this file is the full-annotated reference (templates/_cloudgrid.yaml.reference) with EVERY
|
|
44
|
+
# field present as a comment; only the fields below are uncommented, so it
|
|
45
|
+
# deploys to exactly these active fields.
|
|
46
|
+
name: appointment-booking
|
|
47
|
+
services:
|
|
48
|
+
web:
|
|
49
|
+
type: nextjs
|
|
50
|
+
path: /
|
|
51
|
+
needs:
|
|
52
|
+
database: true
|
|
53
|
+
vault:
|
|
54
|
+
AUTH_PROVIDER_KEY: auth-provider-key
|
|
55
|
+
STRIPE_KEY: stripe-live-key
|
|
56
|
+
STRIPE_WEBHOOK_SECRET: stripe-webhook-secret
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
> **Capability:** `needs: { database: true }` → the deployer provisions Mongo and
|
|
60
|
+
> injects `DATABASE_MONGODB_URL` (+ legacy `MONGODB_URL`). The `vault:` block maps
|
|
61
|
+
> auth/Stripe secrets to env vars — the CloudGrid-correct way to inject
|
|
62
|
+
> credentials. `requires:` is the deprecated v1 alias; don't mix it with `needs:`.
|
|
63
|
+
> A `reminders` cron service is designed (commented) but cron deploy is PENDING
|
|
64
|
+
> #1543. See the capability-map for the full injection table.
|
|
65
|
+
|
|
66
|
+
## Deploy (async, local edition)
|
|
67
|
+
|
|
68
|
+
`gridctl_init` first (creates the entity + link.json), write the app under
|
|
69
|
+
`services/web/`, set the vault secrets with `gridctl_secrets`, `gridctl_plug`
|
|
70
|
+
(async — poll `gridctl_status` to a live URL). If taking deposits, register the
|
|
71
|
+
`/api/webhook` URL in Stripe and re-plug. Re-plug the same entity to update the
|
|
72
|
+
same URL.
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# AGENTS.md — approval-workflow (blueprint)
|
|
2
|
+
|
|
3
|
+
A multi-step approval system: a requester submits a **request**, it advances
|
|
4
|
+
through an ordered chain of **approval steps**, each step is decided (approve /
|
|
5
|
+
reject / delegate) by an assigned approver **role**, and every action is
|
|
6
|
+
recorded. This is a **blueprint** — a structure guide, not app code. Read it,
|
|
7
|
+
then build the Next.js + Mongo app on the grid following the shape below.
|
|
8
|
+
|
|
9
|
+
The proven base shape is `app-with-data` (Next.js + Mongo, App Router, lazy DB
|
|
10
|
+
getter). This blueprint extends it with a state machine, roles, and
|
|
11
|
+
notifications. Fetch that template for the concrete Mongo/CRUD wiring:
|
|
12
|
+
`gridctl_fetch("template", "app-with-data")`, then adapt it to the collections
|
|
13
|
+
here.
|
|
14
|
+
|
|
15
|
+
## 1. File tree
|
|
16
|
+
|
|
17
|
+
Service code MUST live under `services/web/` — `path: /` in `cloudgrid.yaml` is
|
|
18
|
+
the URL mount, NOT the filesystem path. Files at the root fail with
|
|
19
|
+
`Error: Service directory not found: …/services/web`.
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
cloudgrid.yaml # name + services.web (nextjs) + needs:{database:true} (+ vault: for auth)
|
|
23
|
+
services/web/package.json # next, react, react-dom, mongodb (+ auth provider SDK, + stripe if used)
|
|
24
|
+
services/web/middleware.js # auth provider middleware — gates /dashboard + /api behind sign-in
|
|
25
|
+
services/web/lib/db.js # lazy Mongo client from DATABASE_MONGODB_URL (legacy MONGODB_URL fallback)
|
|
26
|
+
services/web/lib/workflow.js # state machine: advance/decide a request across its ordered steps
|
|
27
|
+
services/web/lib/auth.js # read current user + role from the auth provider session
|
|
28
|
+
services/web/lib/notify.js # send step-assigned / decided notifications (email/Slack connector)
|
|
29
|
+
services/web/app/layout.js # root layout + auth provider wrapper
|
|
30
|
+
services/web/app/page.js # server component: my requests + requests awaiting my approval
|
|
31
|
+
services/web/app/request-form.js # client: create a request, choose the approval chain
|
|
32
|
+
services/web/app/requests/[id]/page.js # server: one request, its steps, timeline, decide buttons
|
|
33
|
+
services/web/app/requests/[id]/decide.js # client: approve / reject / delegate the current step
|
|
34
|
+
services/web/app/api/requests/route.js # GET (list mine/pending) / POST (create request + seed steps)
|
|
35
|
+
services/web/app/api/requests/[id]/route.js # GET one request (with steps + audit)
|
|
36
|
+
services/web/app/api/requests/[id]/decide/route.js # POST a decision → advances the state machine
|
|
37
|
+
services/web/app/api/webhooks/auth/route.js # auth provider webhook: upsert users into the `users` collection
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
If an approval gates a payment, add
|
|
41
|
+
`services/web/app/api/checkout/route.js` (create a Stripe Checkout session) and
|
|
42
|
+
`services/web/app/api/webhooks/stripe/route.js` (mark the request paid on
|
|
43
|
+
`checkout.session.completed`).
|
|
44
|
+
|
|
45
|
+
## 2. Mongo collections
|
|
46
|
+
|
|
47
|
+
The grid provisions one Mongo database (see wiring below). Model these
|
|
48
|
+
collections in it:
|
|
49
|
+
|
|
50
|
+
**`users`** — one per person, mirrored from the auth provider.
|
|
51
|
+
- `_id` (ObjectId), `authId` (provider user id, unique), `email`, `name`,
|
|
52
|
+
`role` (enum: `requester` | `approver` | `admin`), `createdAt`.
|
|
53
|
+
|
|
54
|
+
**`requests`** — one per approval request (the aggregate root).
|
|
55
|
+
- `_id`, `title`, `description`, `amount` (optional, if it gates a payment),
|
|
56
|
+
`requesterId` (→ users), `status` (enum: `pending` | `approved` | `rejected`
|
|
57
|
+
| `cancelled`), `currentStep` (int, 0-based index into `steps`), `createdAt`,
|
|
58
|
+
`updatedAt`.
|
|
59
|
+
|
|
60
|
+
**`steps`** — the ordered approval chain for a request (or embed as a `steps: []`
|
|
61
|
+
array on the request document — either works; a separate collection scales better
|
|
62
|
+
for querying "awaiting my approval").
|
|
63
|
+
- `_id`, `requestId` (→ requests), `order` (int, 0-based), `approverRole`
|
|
64
|
+
(which role decides this step) or `approverId` (a specific user),
|
|
65
|
+
`status` (enum: `waiting` | `active` | `approved` | `rejected` | `skipped`),
|
|
66
|
+
`decidedBy` (→ users, nullable), `decidedAt` (nullable), `comment`.
|
|
67
|
+
|
|
68
|
+
**`audit`** — append-only event log (never mutate/delete rows).
|
|
69
|
+
- `_id`, `requestId`, `actorId` (→ users), `action` (enum: `created` |
|
|
70
|
+
`approved` | `rejected` | `delegated` | `cancelled`), `at`, `detail`.
|
|
71
|
+
|
|
72
|
+
Suggested indexes: `requests.requesterId`, `requests.status`,
|
|
73
|
+
`steps.requestId + order`, `steps.approverRole + status`, `audit.requestId + at`.
|
|
74
|
+
|
|
75
|
+
## 3. The state machine (`lib/workflow.js`)
|
|
76
|
+
|
|
77
|
+
The core of this blueprint. Keep the transitions in one module so both the API
|
|
78
|
+
routes and the UI agree on what is legal.
|
|
79
|
+
|
|
80
|
+
- **Create**: seed the `steps` for the request from the chosen chain; set
|
|
81
|
+
`steps[0].status = active`, the rest `waiting`; `request.status = pending`,
|
|
82
|
+
`request.currentStep = 0`; append `audit(created)`.
|
|
83
|
+
- **Approve current step**: only the assigned role/user may decide; mark the
|
|
84
|
+
active step `approved`; if a next step exists, set it `active` and bump
|
|
85
|
+
`currentStep`; else set `request.status = approved`. Append `audit(approved)`.
|
|
86
|
+
- **Reject current step**: mark it `rejected`, set `request.status = rejected`,
|
|
87
|
+
mark remaining `waiting` steps `skipped`. Append `audit(rejected)`.
|
|
88
|
+
- **Delegate**: reassign the active step's `approverId` to another user, append
|
|
89
|
+
`audit(delegated)` — the step stays `active`.
|
|
90
|
+
- Guard every transition against the current `status`/`currentStep` server-side;
|
|
91
|
+
never trust the client to say which step is active.
|
|
92
|
+
- Fire `lib/notify.js` on step activation (notify the new approver) and on final
|
|
93
|
+
decision (notify the requester).
|
|
94
|
+
|
|
95
|
+
## 4. How CloudGrid injects everything
|
|
96
|
+
|
|
97
|
+
- **Mongo (the datastore):** you declare `needs: { database: true }` in
|
|
98
|
+
`cloudgrid.yaml`. You do NOT provision a DB or set a connection string. The
|
|
99
|
+
deployer provisions shared Mongo and injects the connection string as the
|
|
100
|
+
**`DATABASE_MONGODB_URL`** env var (plus the legacy **`MONGODB_URL`** alias) at
|
|
101
|
+
dev-time (`grid dev`) and at runtime (after `grid plug`). Read it in
|
|
102
|
+
`lib/db.js` via `process.env.DATABASE_MONGODB_URL || process.env.MONGODB_URL`
|
|
103
|
+
**lazily, inside the getter — never at module top level**, or `next build`
|
|
104
|
+
fails when it imports the module for route analysis before the var exists.
|
|
105
|
+
- **Secrets (auth / payments) via the `vault:` block:** the CloudGrid-correct way
|
|
106
|
+
to inject secrets is the `vault:` block in `cloudgrid.yaml`, which maps a vault
|
|
107
|
+
item to an env var. This blueprint's yaml has a commented `vault:` block —
|
|
108
|
+
uncomment it and store the real value with `grid secrets set`, then the
|
|
109
|
+
deployer injects it as an env var:
|
|
110
|
+
```yaml
|
|
111
|
+
vault:
|
|
112
|
+
AUTH_PROVIDER_KEY: auth-provider-secret-key # → process.env.AUTH_PROVIDER_KEY
|
|
113
|
+
# STRIPE_KEY: stripe-live-key # → process.env.STRIPE_KEY (if a step gates a payment)
|
|
114
|
+
# SENDGRID_API_KEY: sendgrid-key # → process.env.SENDGRID_API_KEY (email notifications)
|
|
115
|
+
```
|
|
116
|
+
Do NOT hardcode keys and do NOT set `DATABASE_MONGODB_URL`/`MONGODB_URL`
|
|
117
|
+
yourself — the grid injects the DB vars.
|
|
118
|
+
- **AI (optional):** if you add AI (e.g. auto-summarize a request), declare
|
|
119
|
+
`needs: { ai: true }`; the grid injects **`AI_GATEWAY_URL`** and you call it
|
|
120
|
+
through `@cloudgrid-io/ai`.
|
|
121
|
+
- **Non-secret config** → `grid env`. **Secrets** → `grid secrets set` (mapped by
|
|
122
|
+
`vault:`).
|
|
123
|
+
|
|
124
|
+
## 5. Wiring auth (roles) and payments
|
|
125
|
+
|
|
126
|
+
**Auth + roles (required — approvals need to know who you are):**
|
|
127
|
+
1. Add an auth provider SDK to `package.json` (e.g. `@clerk/nextjs` or the Auth0
|
|
128
|
+
Next.js SDK).
|
|
129
|
+
2. Put the provider's publishable key in `services/web/app/layout.js` (client
|
|
130
|
+
wrapper) and the secret key in `process.env.AUTH_PROVIDER_KEY` (from the
|
|
131
|
+
`vault:` block — never inline it).
|
|
132
|
+
3. `services/web/middleware.js` gates `/dashboard`, `/requests/*`, and `/api/*`
|
|
133
|
+
behind sign-in.
|
|
134
|
+
4. `lib/auth.js` reads the current user + `role` from the session; the state
|
|
135
|
+
machine uses `role` to decide who may approve a given step.
|
|
136
|
+
5. `app/api/webhooks/auth/route.js` receives the provider's user-created/updated
|
|
137
|
+
webhook and upserts the person into the `users` collection with a default
|
|
138
|
+
`role: requester`.
|
|
139
|
+
|
|
140
|
+
**Payments (optional — only if an approved request triggers a charge):**
|
|
141
|
+
1. Add `stripe` to `package.json`; put the key in `STRIPE_KEY` via `vault:`.
|
|
142
|
+
2. `app/api/checkout/route.js` creates a Checkout session after the request
|
|
143
|
+
reaches `approved`.
|
|
144
|
+
3. `app/api/webhooks/stripe/route.js` verifies the signature and, on
|
|
145
|
+
`checkout.session.completed`, records payment on the `requests` document.
|
|
146
|
+
|
|
147
|
+
## 6. Deploy steps
|
|
148
|
+
|
|
149
|
+
1. `gridctl_init` an app `<name>` — creates the entity, `.cloudgrid/link.json`,
|
|
150
|
+
and a `cloudgrid.yaml` with an empty `services: {}`. Run `init` FIRST because
|
|
151
|
+
`plug` needs a linked directory.
|
|
152
|
+
2. Fill `cloudgrid.yaml` to this blueprint's shape (copy this template's file):
|
|
153
|
+
`services.web { type: nextjs, path: / }` + `needs: { database: true }` +
|
|
154
|
+
(uncomment) the `vault:` block for `AUTH_PROVIDER_KEY`.
|
|
155
|
+
3. Write the app under `services/web/` following the file tree above.
|
|
156
|
+
4. `grid secrets set` the auth provider key (and Stripe/SendGrid keys if used);
|
|
157
|
+
they are injected via the `vault:` mapping.
|
|
158
|
+
5. (Optional) `grid dev` to run locally against injected Mongo before deploying.
|
|
159
|
+
6. `grid plug` to deploy. A runtime deploy is **async** — the first response is
|
|
160
|
+
`status: building`, not a live URL. Poll `grid status` (surface a liveness
|
|
161
|
+
signal, never a bare silent wait) until it is live, then return the live app
|
|
162
|
+
URL. Re-plug the SAME entity to update the same URL.
|
|
163
|
+
|
|
164
|
+
## 7. Edition note
|
|
165
|
+
|
|
166
|
+
This is a built + deployed container (a **runtime** app), so it requires the
|
|
167
|
+
**local edition** (Claude Code / Claude Desktop) or the CLI. The **hosted**
|
|
168
|
+
edition (Claude Web / hosted MCP) is inline-only and can publish only static
|
|
169
|
+
pages — it CANNOT build this runtime app. On hosted, tell the user plainly and
|
|
170
|
+
offer a static mock instead; do not attempt the runtime path there.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# approval-workflow template (blueprint)
|
|
2
|
+
|
|
3
|
+
A multi-step approval system: a requester submits a request, it advances through
|
|
4
|
+
an ordered chain of approval steps decided by assigned roles (approve / reject /
|
|
5
|
+
delegate), every action is recorded in an append-only audit log, and approvers
|
|
6
|
+
are notified as each step activates. It is a persistent Next.js + Mongo runtime
|
|
7
|
+
app (declares `needs: { database: true }`, extends the proven `app-with-data`
|
|
8
|
+
shape) with auth-provider roles wired through a `vault:` secret. This is a
|
|
9
|
+
**blueprint: structure + cloudgrid.yaml — adapt and build.** Read `AGENTS.md`
|
|
10
|
+
for the full file tree, Mongo collections, the state machine, CloudGrid wiring
|
|
11
|
+
(DB injection, `vault:` secrets, deploy), then build the app following it. There
|
|
12
|
+
is no shipped app code here.
|