@girardmedia/bootspring 1.2.0 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. package/README.md +107 -14
  2. package/bin/bootspring.js +166 -27
  3. package/cli/agent.js +189 -17
  4. package/cli/analyze.js +499 -0
  5. package/cli/audit.js +557 -0
  6. package/cli/auth.js +495 -38
  7. package/cli/billing.js +302 -0
  8. package/cli/build.js +695 -0
  9. package/cli/business.js +109 -26
  10. package/cli/checkpoint-utils.js +168 -0
  11. package/cli/checkpoint.js +639 -0
  12. package/cli/cloud-sync.js +447 -0
  13. package/cli/content.js +198 -0
  14. package/cli/context.js +1 -1
  15. package/cli/deploy.js +543 -0
  16. package/cli/fundraise.js +112 -50
  17. package/cli/github-cmd.js +435 -0
  18. package/cli/health.js +477 -0
  19. package/cli/init.js +84 -13
  20. package/cli/legal.js +107 -95
  21. package/cli/log.js +2 -2
  22. package/cli/loop.js +976 -73
  23. package/cli/manager.js +711 -0
  24. package/cli/metrics.js +480 -0
  25. package/cli/monitor.js +812 -0
  26. package/cli/onboard.js +521 -0
  27. package/cli/orchestrator.js +12 -24
  28. package/cli/prd.js +594 -0
  29. package/cli/preseed-start.js +1483 -0
  30. package/cli/preseed.js +2302 -0
  31. package/cli/project.js +436 -0
  32. package/cli/quality.js +233 -0
  33. package/cli/security.js +913 -0
  34. package/cli/seed.js +1441 -5
  35. package/cli/skill.js +273 -211
  36. package/cli/suggest.js +989 -0
  37. package/cli/switch.js +453 -0
  38. package/cli/visualize.js +527 -0
  39. package/cli/watch.js +769 -0
  40. package/cli/workspace.js +607 -0
  41. package/core/analyze-workflow.js +1134 -0
  42. package/core/api-client.js +535 -22
  43. package/core/audit-workflow.js +1350 -0
  44. package/core/build-orchestrator.js +480 -0
  45. package/core/build-state.js +577 -0
  46. package/core/checkpoint-engine.js +408 -0
  47. package/core/config.js +1109 -26
  48. package/core/context-loader.js +21 -1
  49. package/core/deploy-workflow.js +836 -0
  50. package/core/entitlements.js +93 -22
  51. package/core/github-sync.js +610 -0
  52. package/core/index.js +8 -1
  53. package/core/ingest.js +1111 -0
  54. package/core/metrics-engine.js +768 -0
  55. package/core/onboard-workflow.js +1007 -0
  56. package/core/preseed-workflow.js +934 -0
  57. package/core/preseed.js +1617 -0
  58. package/core/project-context.js +325 -0
  59. package/core/project-state.js +694 -0
  60. package/core/r2-sync.js +583 -0
  61. package/core/scaffold.js +525 -7
  62. package/core/session.js +258 -0
  63. package/core/task-extractor.js +758 -0
  64. package/core/telemetry.js +28 -6
  65. package/core/tier-enforcement.js +737 -0
  66. package/core/utils.js +38 -14
  67. package/generators/questionnaire.js +15 -12
  68. package/generators/sections/ai.js +7 -7
  69. package/generators/sections/content.js +300 -0
  70. package/generators/sections/index.js +3 -0
  71. package/generators/sections/plugins.js +7 -6
  72. package/generators/templates/build-planning.template.js +596 -0
  73. package/generators/templates/content.template.js +819 -0
  74. package/generators/templates/index.js +2 -1
  75. package/hooks/git-autopilot.js +1250 -0
  76. package/hooks/index.js +9 -0
  77. package/intelligence/agent-collab.js +2057 -0
  78. package/intelligence/auto-suggest.js +634 -0
  79. package/intelligence/content-gen.js +1589 -0
  80. package/intelligence/cross-project.js +1647 -0
  81. package/intelligence/index.js +184 -0
  82. package/intelligence/learning/insights.json +517 -7
  83. package/intelligence/learning/pattern-learner.js +1008 -14
  84. package/intelligence/memory/decision-tracker.js +1431 -31
  85. package/intelligence/memory/decisions.jsonl +0 -0
  86. package/intelligence/orchestrator.js +2896 -1
  87. package/intelligence/prd.js +92 -1
  88. package/intelligence/recommendation-weights.json +14 -2
  89. package/intelligence/recommendations.js +463 -9
  90. package/intelligence/workflow-composer.js +1451 -0
  91. package/marketplace/index.d.ts +324 -0
  92. package/marketplace/index.js +1921 -0
  93. package/mcp/contracts/mcp-contract.v1.json +342 -4
  94. package/mcp/registry.js +680 -3
  95. package/mcp/response-formatter.js +23 -0
  96. package/mcp/tools/assist-tool.js +78 -4
  97. package/mcp/tools/autopilot-tool.js +408 -0
  98. package/mcp/tools/content-tool.js +571 -0
  99. package/mcp/tools/dashboard-tool.js +251 -5
  100. package/mcp/tools/mvp-tool.js +344 -0
  101. package/mcp/tools/plugin-tool.js +23 -1
  102. package/mcp/tools/prd-tool.js +579 -0
  103. package/mcp/tools/seed-tool.js +447 -0
  104. package/mcp/tools/skill-tool.js +43 -14
  105. package/mcp/tools/suggest-tool.js +147 -0
  106. package/package.json +15 -6
  107. package/agents/README.md +0 -93
  108. package/agents/ai-integration-expert/context.md +0 -386
  109. package/agents/api-expert/context.md +0 -416
  110. package/agents/architecture-expert/context.md +0 -454
  111. package/agents/auth-expert/context.md +0 -399
  112. package/agents/backend-expert/context.md +0 -483
  113. package/agents/business-strategy-expert/context.md +0 -180
  114. package/agents/code-review-expert/context.md +0 -365
  115. package/agents/competitive-analysis-expert/context.md +0 -239
  116. package/agents/data-modeling-expert/context.md +0 -352
  117. package/agents/database-expert/context.md +0 -250
  118. package/agents/devops-expert/context.md +0 -446
  119. package/agents/email-expert/context.md +0 -379
  120. package/agents/financial-expert/context.md +0 -213
  121. package/agents/frontend-expert/context.md +0 -364
  122. package/agents/fundraising-expert/context.md +0 -257
  123. package/agents/growth-expert/context.md +0 -249
  124. package/agents/index.js +0 -140
  125. package/agents/investor-relations-expert/context.md +0 -266
  126. package/agents/legal-expert/context.md +0 -284
  127. package/agents/marketing-expert/context.md +0 -236
  128. package/agents/monitoring-expert/context.md +0 -362
  129. package/agents/operations-expert/context.md +0 -279
  130. package/agents/partnerships-expert/context.md +0 -286
  131. package/agents/payment-expert/context.md +0 -340
  132. package/agents/performance-expert/context.md +0 -377
  133. package/agents/private-equity-expert/context.md +0 -246
  134. package/agents/railway-expert/context.md +0 -284
  135. package/agents/research-expert/context.md +0 -245
  136. package/agents/sales-expert/context.md +0 -241
  137. package/agents/security-expert/context.md +0 -343
  138. package/agents/testing-expert/context.md +0 -414
  139. package/agents/ui-ux-expert/context.md +0 -448
  140. package/agents/vercel-expert/context.md +0 -426
  141. package/skills/index.js +0 -787
  142. package/skills/patterns/README.md +0 -163
  143. package/skills/patterns/ai/agents.md +0 -281
  144. package/skills/patterns/ai/claude.md +0 -138
  145. package/skills/patterns/ai/embeddings.md +0 -150
  146. package/skills/patterns/ai/rag.md +0 -266
  147. package/skills/patterns/ai/streaming.md +0 -170
  148. package/skills/patterns/ai/structured-output.md +0 -162
  149. package/skills/patterns/ai/tools.md +0 -154
  150. package/skills/patterns/analytics/tracking.md +0 -220
  151. package/skills/patterns/api/errors.md +0 -296
  152. package/skills/patterns/api/graphql.md +0 -440
  153. package/skills/patterns/api/middleware.md +0 -279
  154. package/skills/patterns/api/openapi.md +0 -285
  155. package/skills/patterns/api/rate-limiting.md +0 -231
  156. package/skills/patterns/api/route-handler.md +0 -217
  157. package/skills/patterns/api/server-action.md +0 -249
  158. package/skills/patterns/api/versioning.md +0 -443
  159. package/skills/patterns/api/webhooks.md +0 -247
  160. package/skills/patterns/auth/clerk.md +0 -132
  161. package/skills/patterns/auth/mfa.md +0 -313
  162. package/skills/patterns/auth/nextauth.md +0 -140
  163. package/skills/patterns/auth/oauth.md +0 -237
  164. package/skills/patterns/auth/rbac.md +0 -152
  165. package/skills/patterns/auth/session-management.md +0 -367
  166. package/skills/patterns/auth/session.md +0 -120
  167. package/skills/patterns/database/audit.md +0 -177
  168. package/skills/patterns/database/migrations.md +0 -177
  169. package/skills/patterns/database/pagination.md +0 -230
  170. package/skills/patterns/database/pooling.md +0 -357
  171. package/skills/patterns/database/prisma.md +0 -180
  172. package/skills/patterns/database/relations.md +0 -187
  173. package/skills/patterns/database/seeding.md +0 -246
  174. package/skills/patterns/database/soft-delete.md +0 -153
  175. package/skills/patterns/database/transactions.md +0 -162
  176. package/skills/patterns/deployment/ci-cd.md +0 -231
  177. package/skills/patterns/deployment/docker.md +0 -188
  178. package/skills/patterns/deployment/monitoring.md +0 -387
  179. package/skills/patterns/deployment/vercel.md +0 -160
  180. package/skills/patterns/email/resend.md +0 -143
  181. package/skills/patterns/email/templates.md +0 -245
  182. package/skills/patterns/email/transactional.md +0 -503
  183. package/skills/patterns/email/verification.md +0 -176
  184. package/skills/patterns/files/download.md +0 -243
  185. package/skills/patterns/files/upload.md +0 -239
  186. package/skills/patterns/i18n/nextintl.md +0 -188
  187. package/skills/patterns/logging/structured.md +0 -292
  188. package/skills/patterns/notifications/email-queue.md +0 -248
  189. package/skills/patterns/notifications/push.md +0 -279
  190. package/skills/patterns/payments/checkout.md +0 -303
  191. package/skills/patterns/payments/invoices.md +0 -287
  192. package/skills/patterns/payments/portal.md +0 -245
  193. package/skills/patterns/payments/stripe.md +0 -272
  194. package/skills/patterns/payments/subscriptions.md +0 -300
  195. package/skills/patterns/payments/usage.md +0 -279
  196. package/skills/patterns/performance/caching.md +0 -276
  197. package/skills/patterns/performance/code-splitting.md +0 -233
  198. package/skills/patterns/performance/edge.md +0 -254
  199. package/skills/patterns/performance/isr.md +0 -266
  200. package/skills/patterns/performance/lazy-loading.md +0 -281
  201. package/skills/patterns/realtime/sse.md +0 -327
  202. package/skills/patterns/realtime/websockets.md +0 -336
  203. package/skills/patterns/search/filtering.md +0 -329
  204. package/skills/patterns/search/fulltext.md +0 -260
  205. package/skills/patterns/security/audit-logging.md +0 -444
  206. package/skills/patterns/security/csrf.md +0 -234
  207. package/skills/patterns/security/headers.md +0 -252
  208. package/skills/patterns/security/sanitization.md +0 -258
  209. package/skills/patterns/security/secrets.md +0 -261
  210. package/skills/patterns/security/validation.md +0 -268
  211. package/skills/patterns/security/xss.md +0 -229
  212. package/skills/patterns/seo/metadata.md +0 -252
  213. package/skills/patterns/state/context.md +0 -349
  214. package/skills/patterns/state/react-query.md +0 -313
  215. package/skills/patterns/state/url-state.md +0 -482
  216. package/skills/patterns/state/zustand.md +0 -262
  217. package/skills/patterns/testing/api.md +0 -259
  218. package/skills/patterns/testing/component.md +0 -233
  219. package/skills/patterns/testing/coverage.md +0 -207
  220. package/skills/patterns/testing/fixtures.md +0 -225
  221. package/skills/patterns/testing/integration.md +0 -436
  222. package/skills/patterns/testing/mocking.md +0 -177
  223. package/skills/patterns/testing/playwright.md +0 -162
  224. package/skills/patterns/testing/snapshot.md +0 -175
  225. package/skills/patterns/testing/vitest.md +0 -307
  226. package/skills/patterns/ui/accordions.md +0 -395
  227. package/skills/patterns/ui/cards.md +0 -299
  228. package/skills/patterns/ui/dropdowns.md +0 -476
  229. package/skills/patterns/ui/empty-states.md +0 -320
  230. package/skills/patterns/ui/forms.md +0 -405
  231. package/skills/patterns/ui/inputs.md +0 -319
  232. package/skills/patterns/ui/layouts.md +0 -282
  233. package/skills/patterns/ui/loading.md +0 -291
  234. package/skills/patterns/ui/modals.md +0 -338
  235. package/skills/patterns/ui/navigation.md +0 -374
  236. package/skills/patterns/ui/tables.md +0 -407
  237. package/skills/patterns/ui/toasts.md +0 -300
  238. package/skills/patterns/ui/tooltips.md +0 -396
  239. package/skills/patterns/utils/dates.md +0 -435
  240. package/skills/patterns/utils/errors.md +0 -451
  241. package/skills/patterns/utils/formatting.md +0 -345
  242. package/skills/patterns/utils/validation.md +0 -434
  243. package/templates/bootspring.config.js +0 -83
  244. package/templates/business/business-model-canvas.md +0 -246
  245. package/templates/business/business-plan.md +0 -266
  246. package/templates/business/competitive-analysis.md +0 -312
  247. package/templates/fundraising/data-room-checklist.md +0 -300
  248. package/templates/fundraising/investor-research.md +0 -243
  249. package/templates/fundraising/pitch-deck-outline.md +0 -253
  250. package/templates/legal/gdpr-checklist.md +0 -339
  251. package/templates/legal/privacy-policy.md +0 -285
  252. package/templates/legal/terms-of-service.md +0 -222
  253. package/templates/mcp.json +0 -9
@@ -1,387 +0,0 @@
1
- # Monitoring and Observability Patterns
2
-
3
- Patterns for application monitoring, logging, and observability.
4
-
5
- ## OpenTelemetry Setup
6
-
7
- ```typescript
8
- // instrumentation.ts (Next.js)
9
- import { NodeSDK } from '@opentelemetry/sdk-node'
10
- import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'
11
- import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'
12
- import { Resource } from '@opentelemetry/resources'
13
- import { SEMRESATTRS_SERVICE_NAME, SEMRESATTRS_SERVICE_VERSION } from '@opentelemetry/semantic-conventions'
14
-
15
- export function register() {
16
- if (process.env.NEXT_RUNTIME === 'nodejs') {
17
- const sdk = new NodeSDK({
18
- resource: new Resource({
19
- [SEMRESATTRS_SERVICE_NAME]: 'my-nextjs-app',
20
- [SEMRESATTRS_SERVICE_VERSION]: process.env.npm_package_version ?? '1.0.0'
21
- }),
22
- traceExporter: new OTLPTraceExporter({
23
- url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT
24
- }),
25
- instrumentations: [getNodeAutoInstrumentations()]
26
- })
27
-
28
- sdk.start()
29
- }
30
- }
31
- ```
32
-
33
- ## Custom Metrics
34
-
35
- ```typescript
36
- // lib/metrics.ts
37
- import { Counter, Histogram, Registry } from 'prom-client'
38
-
39
- const register = new Registry()
40
-
41
- // HTTP request metrics
42
- export const httpRequestsTotal = new Counter({
43
- name: 'http_requests_total',
44
- help: 'Total number of HTTP requests',
45
- labelNames: ['method', 'path', 'status'],
46
- registers: [register]
47
- })
48
-
49
- export const httpRequestDuration = new Histogram({
50
- name: 'http_request_duration_seconds',
51
- help: 'HTTP request duration in seconds',
52
- labelNames: ['method', 'path'],
53
- buckets: [0.01, 0.05, 0.1, 0.5, 1, 2, 5],
54
- registers: [register]
55
- })
56
-
57
- // Business metrics
58
- export const userSignups = new Counter({
59
- name: 'user_signups_total',
60
- help: 'Total number of user signups',
61
- labelNames: ['plan'],
62
- registers: [register]
63
- })
64
-
65
- export const apiCalls = new Counter({
66
- name: 'api_calls_total',
67
- help: 'Total API calls',
68
- labelNames: ['endpoint', 'status'],
69
- registers: [register]
70
- })
71
-
72
- export { register }
73
-
74
- // API endpoint for Prometheus
75
- // app/api/metrics/route.ts
76
- import { NextResponse } from 'next/server'
77
- import { register } from '@/lib/metrics'
78
-
79
- export async function GET() {
80
- const metrics = await register.metrics()
81
- return new NextResponse(metrics, {
82
- headers: {
83
- 'Content-Type': register.contentType
84
- }
85
- })
86
- }
87
- ```
88
-
89
- ## Request Tracing Middleware
90
-
91
- ```typescript
92
- // middleware.ts
93
- import { NextRequest, NextResponse } from 'next/server'
94
- import { httpRequestsTotal, httpRequestDuration } from '@/lib/metrics'
95
- import { v4 as uuidv4 } from 'uuid'
96
-
97
- export function middleware(request: NextRequest) {
98
- const requestId = uuidv4()
99
- const start = Date.now()
100
-
101
- // Add request ID header
102
- const response = NextResponse.next()
103
- response.headers.set('X-Request-ID', requestId)
104
-
105
- // Log request
106
- console.log(JSON.stringify({
107
- type: 'request',
108
- requestId,
109
- method: request.method,
110
- path: request.nextUrl.pathname,
111
- timestamp: new Date().toISOString()
112
- }))
113
-
114
- return response
115
- }
116
-
117
- // Middleware for API routes
118
- // lib/withMetrics.ts
119
- import { NextRequest, NextResponse } from 'next/server'
120
- import { httpRequestsTotal, httpRequestDuration } from '@/lib/metrics'
121
-
122
- type Handler = (req: NextRequest) => Promise<NextResponse>
123
-
124
- export function withMetrics(handler: Handler): Handler {
125
- return async (req: NextRequest) => {
126
- const start = Date.now()
127
- const path = req.nextUrl.pathname
128
-
129
- try {
130
- const response = await handler(req)
131
- const duration = (Date.now() - start) / 1000
132
-
133
- httpRequestsTotal.inc({
134
- method: req.method,
135
- path,
136
- status: response.status
137
- })
138
-
139
- httpRequestDuration.observe({ method: req.method, path }, duration)
140
-
141
- return response
142
- } catch (error) {
143
- httpRequestsTotal.inc({
144
- method: req.method,
145
- path,
146
- status: 500
147
- })
148
- throw error
149
- }
150
- }
151
- }
152
- ```
153
-
154
- ## Error Tracking with Sentry
155
-
156
- ```typescript
157
- // sentry.client.config.ts
158
- import * as Sentry from '@sentry/nextjs'
159
-
160
- Sentry.init({
161
- dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
162
- environment: process.env.NODE_ENV,
163
- tracesSampleRate: 1.0,
164
- replaysSessionSampleRate: 0.1,
165
- replaysOnErrorSampleRate: 1.0,
166
- integrations: [
167
- Sentry.replayIntegration({
168
- maskAllText: true,
169
- blockAllMedia: true
170
- })
171
- ]
172
- })
173
-
174
- // sentry.server.config.ts
175
- import * as Sentry from '@sentry/nextjs'
176
-
177
- Sentry.init({
178
- dsn: process.env.SENTRY_DSN,
179
- environment: process.env.NODE_ENV,
180
- tracesSampleRate: 1.0
181
- })
182
-
183
- // lib/error-tracking.ts
184
- import * as Sentry from '@sentry/nextjs'
185
-
186
- export function captureError(error: Error, context?: Record<string, any>) {
187
- Sentry.withScope(scope => {
188
- if (context) {
189
- scope.setExtras(context)
190
- }
191
- Sentry.captureException(error)
192
- })
193
- }
194
-
195
- export function setUserContext(user: { id: string; email: string }) {
196
- Sentry.setUser({ id: user.id, email: user.email })
197
- }
198
-
199
- export function addBreadcrumb(message: string, data?: Record<string, any>) {
200
- Sentry.addBreadcrumb({
201
- message,
202
- data,
203
- level: 'info'
204
- })
205
- }
206
- ```
207
-
208
- ## Health Check Endpoints
209
-
210
- ```typescript
211
- // app/api/health/route.ts
212
- import { NextResponse } from 'next/server'
213
- import { prisma } from '@/lib/db'
214
- import { redis } from '@/lib/redis'
215
-
216
- interface HealthCheck {
217
- status: 'healthy' | 'unhealthy'
218
- checks: {
219
- [key: string]: {
220
- status: 'pass' | 'fail'
221
- responseTime?: number
222
- error?: string
223
- }
224
- }
225
- timestamp: string
226
- }
227
-
228
- export async function GET() {
229
- const checks: HealthCheck['checks'] = {}
230
-
231
- // Database check
232
- const dbStart = Date.now()
233
- try {
234
- await prisma.$queryRaw`SELECT 1`
235
- checks.database = {
236
- status: 'pass',
237
- responseTime: Date.now() - dbStart
238
- }
239
- } catch (error) {
240
- checks.database = {
241
- status: 'fail',
242
- error: error instanceof Error ? error.message : 'Unknown error'
243
- }
244
- }
245
-
246
- // Redis check
247
- const redisStart = Date.now()
248
- try {
249
- await redis.ping()
250
- checks.redis = {
251
- status: 'pass',
252
- responseTime: Date.now() - redisStart
253
- }
254
- } catch (error) {
255
- checks.redis = {
256
- status: 'fail',
257
- error: error instanceof Error ? error.message : 'Unknown error'
258
- }
259
- }
260
-
261
- const allHealthy = Object.values(checks).every(c => c.status === 'pass')
262
-
263
- const response: HealthCheck = {
264
- status: allHealthy ? 'healthy' : 'unhealthy',
265
- checks,
266
- timestamp: new Date().toISOString()
267
- }
268
-
269
- return NextResponse.json(response, {
270
- status: allHealthy ? 200 : 503
271
- })
272
- }
273
-
274
- // app/api/health/ready/route.ts
275
- export async function GET() {
276
- // Kubernetes readiness probe
277
- return NextResponse.json({ ready: true })
278
- }
279
-
280
- // app/api/health/live/route.ts
281
- export async function GET() {
282
- // Kubernetes liveness probe
283
- return NextResponse.json({ alive: true })
284
- }
285
- ```
286
-
287
- ## Performance Monitoring
288
-
289
- ```typescript
290
- // lib/performance.ts
291
- import { trace, SpanStatusCode } from '@opentelemetry/api'
292
-
293
- const tracer = trace.getTracer('my-app')
294
-
295
- export async function withSpan<T>(
296
- name: string,
297
- fn: () => Promise<T>,
298
- attributes?: Record<string, string | number>
299
- ): Promise<T> {
300
- return tracer.startActiveSpan(name, async span => {
301
- if (attributes) {
302
- span.setAttributes(attributes)
303
- }
304
-
305
- try {
306
- const result = await fn()
307
- span.setStatus({ code: SpanStatusCode.OK })
308
- return result
309
- } catch (error) {
310
- span.setStatus({
311
- code: SpanStatusCode.ERROR,
312
- message: error instanceof Error ? error.message : 'Unknown error'
313
- })
314
- span.recordException(error as Error)
315
- throw error
316
- } finally {
317
- span.end()
318
- }
319
- })
320
- }
321
-
322
- // Usage
323
- const users = await withSpan(
324
- 'fetch-users',
325
- () => prisma.user.findMany(),
326
- { 'db.operation': 'findMany', 'db.table': 'users' }
327
- )
328
- ```
329
-
330
- ## Dashboard Configuration
331
-
332
- ```yaml
333
- # docker-compose.monitoring.yml
334
- version: '3.8'
335
- services:
336
- prometheus:
337
- image: prom/prometheus:latest
338
- ports:
339
- - '9090:9090'
340
- volumes:
341
- - ./prometheus.yml:/etc/prometheus/prometheus.yml
342
- - prometheus_data:/prometheus
343
- command:
344
- - '--config.file=/etc/prometheus/prometheus.yml'
345
- - '--storage.tsdb.path=/prometheus'
346
-
347
- grafana:
348
- image: grafana/grafana:latest
349
- ports:
350
- - '3001:3000'
351
- volumes:
352
- - grafana_data:/var/lib/grafana
353
- - ./grafana/dashboards:/etc/grafana/provisioning/dashboards
354
- - ./grafana/datasources:/etc/grafana/provisioning/datasources
355
- environment:
356
- - GF_SECURITY_ADMIN_PASSWORD=admin
357
-
358
- jaeger:
359
- image: jaegertracing/all-in-one:latest
360
- ports:
361
- - '16686:16686'
362
- - '4317:4317'
363
- - '4318:4318'
364
-
365
- volumes:
366
- prometheus_data:
367
- grafana_data:
368
- ```
369
-
370
- ```yaml
371
- # prometheus.yml
372
- global:
373
- scrape_interval: 15s
374
-
375
- scrape_configs:
376
- - job_name: 'nextjs-app'
377
- static_configs:
378
- - targets: ['host.docker.internal:3000']
379
- metrics_path: '/api/metrics'
380
- ```
381
-
382
- ## When to Use
383
-
384
- - Production deployments
385
- - Performance debugging
386
- - Error tracking
387
- - SLA monitoring
@@ -1,160 +0,0 @@
1
- # Vercel Deployment Patterns
2
-
3
- Patterns for deploying to Vercel.
4
-
5
- ## Environment Variables
6
-
7
- ```bash
8
- # .env.local (local development)
9
- DATABASE_URL="postgresql://..."
10
- NEXTAUTH_SECRET="..."
11
-
12
- # Vercel Dashboard: Settings > Environment Variables
13
- # Or via CLI:
14
- vercel env add DATABASE_URL production
15
- vercel env add NEXTAUTH_SECRET production
16
- ```
17
-
18
- ## vercel.json Configuration
19
-
20
- ```json
21
- {
22
- "framework": "nextjs",
23
- "regions": ["iad1"],
24
- "headers": [
25
- {
26
- "source": "/api/(.*)",
27
- "headers": [
28
- { "key": "Access-Control-Allow-Origin", "value": "*" }
29
- ]
30
- }
31
- ],
32
- "redirects": [
33
- {
34
- "source": "/old-page",
35
- "destination": "/new-page",
36
- "permanent": true
37
- }
38
- ],
39
- "rewrites": [
40
- {
41
- "source": "/api/proxy/:path*",
42
- "destination": "https://api.external.com/:path*"
43
- }
44
- ],
45
- "crons": [
46
- {
47
- "path": "/api/cron/daily",
48
- "schedule": "0 0 * * *"
49
- }
50
- ]
51
- }
52
- ```
53
-
54
- ## Preview Deployments
55
-
56
- ```typescript
57
- // lib/env.ts
58
- export function getBaseUrl() {
59
- // Vercel preview deployments
60
- if (process.env.VERCEL_URL) {
61
- return `https://${process.env.VERCEL_URL}`
62
- }
63
-
64
- // Production
65
- if (process.env.NEXT_PUBLIC_APP_URL) {
66
- return process.env.NEXT_PUBLIC_APP_URL
67
- }
68
-
69
- // Local development
70
- return 'http://localhost:3000'
71
- }
72
- ```
73
-
74
- ## Cron Jobs
75
-
76
- ```typescript
77
- // app/api/cron/cleanup/route.ts
78
- import { NextResponse } from 'next/server'
79
-
80
- export async function GET(request: Request) {
81
- // Verify cron secret
82
- const authHeader = request.headers.get('authorization')
83
-
84
- if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) {
85
- return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
86
- }
87
-
88
- // Run cleanup task
89
- await prisma.session.deleteMany({
90
- where: { expiresAt: { lt: new Date() } }
91
- })
92
-
93
- return NextResponse.json({ success: true })
94
- }
95
-
96
- // vercel.json
97
- {
98
- "crons": [{
99
- "path": "/api/cron/cleanup",
100
- "schedule": "0 */6 * * *"
101
- }]
102
- }
103
- ```
104
-
105
- ## Edge Functions
106
-
107
- ```typescript
108
- // app/api/geo/route.ts
109
- export const runtime = 'edge'
110
- export const preferredRegion = ['iad1', 'sfo1', 'fra1']
111
-
112
- export async function GET(request: Request) {
113
- // Access Vercel geo headers
114
- const country = request.headers.get('x-vercel-ip-country')
115
- const city = request.headers.get('x-vercel-ip-city')
116
-
117
- return Response.json({ country, city })
118
- }
119
- ```
120
-
121
- ## Build Configuration
122
-
123
- ```typescript
124
- // next.config.js
125
- module.exports = {
126
- // Standalone output for containers
127
- output: 'standalone',
128
-
129
- // Image optimization
130
- images: {
131
- domains: ['cdn.example.com'],
132
- remotePatterns: [
133
- { protocol: 'https', hostname: '**.example.com' }
134
- ]
135
- },
136
-
137
- // Environment at build time
138
- env: {
139
- BUILD_TIME: new Date().toISOString()
140
- }
141
- }
142
- ```
143
-
144
- ## Deploy Hooks
145
-
146
- ```bash
147
- # Trigger deploy via webhook
148
- curl -X POST https://api.vercel.com/v1/integrations/deploy/prj_xxx/hook_xxx
149
-
150
- # In CI/CD
151
- - name: Deploy to Vercel
152
- run: curl -X POST ${{ secrets.VERCEL_DEPLOY_HOOK }}
153
- ```
154
-
155
- ## When to Use
156
-
157
- - Next.js production
158
- - Preview environments
159
- - Scheduled tasks
160
- - Edge computing
@@ -1,143 +0,0 @@
1
- # Resend Email Patterns
2
-
3
- Patterns for sending emails with Resend.
4
-
5
- ## Client Setup
6
-
7
- ```typescript
8
- // lib/email.ts
9
- import { Resend } from 'resend'
10
-
11
- export const resend = new Resend(process.env.RESEND_API_KEY)
12
- ```
13
-
14
- ## Send Basic Email
15
-
16
- ```typescript
17
- // lib/email.ts
18
- export async function sendEmail({
19
- to,
20
- subject,
21
- html
22
- }: {
23
- to: string
24
- subject: string
25
- html: string
26
- }) {
27
- const { data, error } = await resend.emails.send({
28
- from: 'Your App <noreply@yourapp.com>',
29
- to,
30
- subject,
31
- html
32
- })
33
-
34
- if (error) {
35
- console.error('Email error:', error)
36
- throw error
37
- }
38
-
39
- return data
40
- }
41
- ```
42
-
43
- ## With React Email
44
-
45
- ```typescript
46
- // lib/email.ts
47
- import { render } from '@react-email/render'
48
- import { WelcomeEmail } from '@/emails/welcome'
49
-
50
- export async function sendWelcomeEmail(to: string, name: string) {
51
- const html = await render(
52
- WelcomeEmail({ name, actionUrl: `${process.env.NEXT_PUBLIC_APP_URL}/dashboard` })
53
- )
54
-
55
- return resend.emails.send({
56
- from: 'Your App <welcome@yourapp.com>',
57
- to,
58
- subject: 'Welcome to Our App!',
59
- html
60
- })
61
- }
62
- ```
63
-
64
- ## Email Service Pattern
65
-
66
- ```typescript
67
- // lib/email-service.ts
68
- import { resend } from './email'
69
- import { render } from '@react-email/render'
70
- import { WelcomeEmail } from '@/emails/welcome'
71
- import { PasswordResetEmail } from '@/emails/password-reset'
72
- import { InviteEmail } from '@/emails/invite'
73
-
74
- export const emailService = {
75
- async sendWelcome(to: string, name: string) {
76
- const html = await render(
77
- WelcomeEmail({
78
- name,
79
- actionUrl: `${process.env.NEXT_PUBLIC_APP_URL}/dashboard`
80
- })
81
- )
82
-
83
- return resend.emails.send({
84
- from: 'Your App <welcome@yourapp.com>',
85
- to,
86
- subject: 'Welcome to Our App!',
87
- html
88
- })
89
- },
90
-
91
- async sendPasswordReset(to: string, resetUrl: string) {
92
- const html = await render(PasswordResetEmail({ resetUrl }))
93
-
94
- return resend.emails.send({
95
- from: 'Your App <security@yourapp.com>',
96
- to,
97
- subject: 'Reset Your Password',
98
- html
99
- })
100
- },
101
-
102
- async sendInvite(
103
- to: string,
104
- inviterName: string,
105
- teamName: string,
106
- inviteUrl: string
107
- ) {
108
- const html = await render(
109
- InviteEmail({ inviterName, teamName, inviteUrl })
110
- )
111
-
112
- return resend.emails.send({
113
- from: 'Your App <invites@yourapp.com>',
114
- to,
115
- subject: `${inviterName} invited you to join ${teamName}`,
116
- html
117
- })
118
- }
119
- }
120
- ```
121
-
122
- ## Batch Sending
123
-
124
- ```typescript
125
- // lib/email.ts
126
- export async function sendBatch(
127
- emails: { to: string; subject: string; html: string }[]
128
- ) {
129
- return resend.batch.send(
130
- emails.map((email) => ({
131
- from: 'Your App <noreply@yourapp.com>',
132
- ...email
133
- }))
134
- )
135
- }
136
- ```
137
-
138
- ## When to Use
139
-
140
- - Transactional emails
141
- - Welcome sequences
142
- - Password resets
143
- - Notifications