leedstack 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +364 -0
  3. package/bin/create-stack.js +277 -0
  4. package/package.json +60 -0
  5. package/tools/templates/backend/go-echo/backend/.env.example +10 -0
  6. package/tools/templates/backend/go-echo/backend/cmd/server/main.go.ejs +57 -0
  7. package/tools/templates/backend/go-echo/backend/go.mod.ejs +10 -0
  8. package/tools/templates/backend/go-echo/backend/internal/handlers/example.go +15 -0
  9. package/tools/templates/backend/go-echo/backend/internal/handlers/health.go +13 -0
  10. package/tools/templates/backend/java-spring/backend/.env.example +10 -0
  11. package/tools/templates/backend/java-spring/backend/pom.xml.ejs +64 -0
  12. package/tools/templates/backend/java-spring/backend/src/main/java/com/app/Application.java.ejs +11 -0
  13. package/tools/templates/backend/java-spring/backend/src/main/java/com/app/config/SecurityConfig.java.ejs +64 -0
  14. package/tools/templates/backend/java-spring/backend/src/main/java/com/app/controller/ExampleController.java +19 -0
  15. package/tools/templates/backend/java-spring/backend/src/main/java/com/app/controller/HealthController.java +15 -0
  16. package/tools/templates/backend/java-spring/backend/src/main/resources/application.yml.ejs +20 -0
  17. package/tools/templates/backend/node-express/backend/.env.example +10 -0
  18. package/tools/templates/backend/node-express/backend/.eslintrc.json +21 -0
  19. package/tools/templates/backend/node-express/backend/.prettierrc +10 -0
  20. package/tools/templates/backend/node-express/backend/Dockerfile +52 -0
  21. package/tools/templates/backend/node-express/backend/README.md +68 -0
  22. package/tools/templates/backend/node-express/backend/package.json.ejs +37 -0
  23. package/tools/templates/backend/node-express/backend/src/index.ts.ejs +75 -0
  24. package/tools/templates/backend/node-express/backend/src/routes/health.ts +54 -0
  25. package/tools/templates/backend/node-express/backend/tsconfig.json +17 -0
  26. package/tools/templates/backend/python-fastapi/backend/.env.example +18 -0
  27. package/tools/templates/backend/python-fastapi/backend/README.md +73 -0
  28. package/tools/templates/backend/python-fastapi/backend/app/__init__.py +1 -0
  29. package/tools/templates/backend/python-fastapi/backend/app/main.py.ejs +68 -0
  30. package/tools/templates/backend/python-fastapi/backend/requirements.txt.ejs +22 -0
  31. package/tools/templates/base/.dockerignore +16 -0
  32. package/tools/templates/base/.env.example +31 -0
  33. package/tools/templates/base/.github/workflows/ci.yml.ejs +124 -0
  34. package/tools/templates/base/.github/workflows/deploy-separate.yml.example +144 -0
  35. package/tools/templates/base/.vscode/extensions.json +17 -0
  36. package/tools/templates/base/.vscode/settings.json +49 -0
  37. package/tools/templates/base/Makefile +98 -0
  38. package/tools/templates/base/README.md.ejs +118 -0
  39. package/tools/templates/base/docker-compose.yml.ejs +49 -0
  40. package/tools/templates/base/package.json.ejs +30 -0
  41. package/tools/templates/base/scripts/split-repos.sh +189 -0
  42. package/tools/templates/db/postgres/backend/java-spring/backend/pom.xml.ejs +81 -0
  43. package/tools/templates/db/postgres/backend/java-spring/backend/src/main/resources/application.yml.ejs +39 -0
  44. package/tools/templates/db/postgres/backend/java-spring/backend/src/main/resources/db/migration/V1__init.sql +17 -0
  45. package/tools/templates/db/postgres/backend/node-express/backend/.env.example +10 -0
  46. package/tools/templates/db/postgres/backend/node-express/backend/package.json.ejs +32 -0
  47. package/tools/templates/db/postgres/backend/node-express/backend/prisma/schema.prisma.ejs +39 -0
  48. package/tools/templates/frontend/angular/frontend/.env.example +9 -0
  49. package/tools/templates/frontend/angular/frontend/angular.json +66 -0
  50. package/tools/templates/frontend/angular/frontend/package.json.ejs +31 -0
  51. package/tools/templates/frontend/angular/frontend/src/app/app.component.ts +30 -0
  52. package/tools/templates/frontend/angular/frontend/src/app/app.routes.ts +18 -0
  53. package/tools/templates/frontend/angular/frontend/src/app/components/home.component.ts +24 -0
  54. package/tools/templates/frontend/angular/frontend/src/app/services/api.service.ts +48 -0
  55. package/tools/templates/frontend/angular/frontend/src/favicon.ico +1 -0
  56. package/tools/templates/frontend/angular/frontend/src/index.html +13 -0
  57. package/tools/templates/frontend/angular/frontend/src/main.ts +10 -0
  58. package/tools/templates/frontend/angular/frontend/src/styles.css +31 -0
  59. package/tools/templates/frontend/angular/frontend/tsconfig.app.json +9 -0
  60. package/tools/templates/frontend/angular/frontend/tsconfig.json +27 -0
  61. package/tools/templates/frontend/nextjs/frontend/.env.example +9 -0
  62. package/tools/templates/frontend/nextjs/frontend/next.config.js +37 -0
  63. package/tools/templates/frontend/nextjs/frontend/package.json.ejs +25 -0
  64. package/tools/templates/frontend/nextjs/frontend/src/app/globals.css +31 -0
  65. package/tools/templates/frontend/nextjs/frontend/src/app/layout.tsx +36 -0
  66. package/tools/templates/frontend/nextjs/frontend/src/app/page.tsx +19 -0
  67. package/tools/templates/frontend/nextjs/frontend/src/lib/api.ts +45 -0
  68. package/tools/templates/frontend/nextjs/frontend/tsconfig.json +27 -0
  69. package/tools/templates/frontend/react/frontend/.env.example +9 -0
  70. package/tools/templates/frontend/react/frontend/.eslintrc.json +32 -0
  71. package/tools/templates/frontend/react/frontend/.prettierrc +10 -0
  72. package/tools/templates/frontend/react/frontend/Dockerfile +37 -0
  73. package/tools/templates/frontend/react/frontend/README.md +54 -0
  74. package/tools/templates/frontend/react/frontend/index.html +13 -0
  75. package/tools/templates/frontend/react/frontend/nginx.conf +35 -0
  76. package/tools/templates/frontend/react/frontend/package.json.ejs +41 -0
  77. package/tools/templates/frontend/react/frontend/public/vite.svg +4 -0
  78. package/tools/templates/frontend/react/frontend/src/App.css +65 -0
  79. package/tools/templates/frontend/react/frontend/src/App.jsx +41 -0
  80. package/tools/templates/frontend/react/frontend/src/assets/react.svg +7 -0
  81. package/tools/templates/frontend/react/frontend/src/components/ErrorBoundary.jsx +62 -0
  82. package/tools/templates/frontend/react/frontend/src/components/Home.jsx +58 -0
  83. package/tools/templates/frontend/react/frontend/src/components/__tests__/Home.test.jsx +74 -0
  84. package/tools/templates/frontend/react/frontend/src/index.css +31 -0
  85. package/tools/templates/frontend/react/frontend/src/lib/api.js +42 -0
  86. package/tools/templates/frontend/react/frontend/src/lib/env.js +58 -0
  87. package/tools/templates/frontend/react/frontend/src/main.jsx +16 -0
  88. package/tools/templates/frontend/react/frontend/src/setupTests.js +8 -0
  89. package/tools/templates/frontend/react/frontend/vite.config.js +30 -0
  90. package/tools/templates/frontend/react/frontend/vitest.config.js +20 -0
  91. package/tools/templates/frontend/svelte/frontend/.env.example +9 -0
  92. package/tools/templates/frontend/svelte/frontend/package.json.ejs +21 -0
  93. package/tools/templates/frontend/svelte/frontend/src/app.html +12 -0
  94. package/tools/templates/frontend/svelte/frontend/src/lib/api.ts +45 -0
  95. package/tools/templates/frontend/svelte/frontend/src/routes/+layout.svelte +56 -0
  96. package/tools/templates/frontend/svelte/frontend/src/routes/+page.svelte +20 -0
  97. package/tools/templates/frontend/svelte/frontend/static/favicon.png +1 -0
  98. package/tools/templates/frontend/svelte/frontend/svelte.config.js +10 -0
  99. package/tools/templates/frontend/svelte/frontend/vite.config.js +9 -0
  100. package/tools/templates/frontend/vue/frontend/.env.example +9 -0
  101. package/tools/templates/frontend/vue/frontend/index.html +13 -0
  102. package/tools/templates/frontend/vue/frontend/package.json.ejs +20 -0
  103. package/tools/templates/frontend/vue/frontend/src/App.vue +60 -0
  104. package/tools/templates/frontend/vue/frontend/src/lib/api.js +42 -0
  105. package/tools/templates/frontend/vue/frontend/src/main.js +33 -0
  106. package/tools/templates/frontend/vue/frontend/src/views/ApiTest.vue +39 -0
  107. package/tools/templates/frontend/vue/frontend/src/views/Home.vue +30 -0
  108. package/tools/templates/frontend/vue/frontend/vite.config.js +9 -0
  109. package/tools/templates/modules/admin/backend/java-spring/backend/src/main/java/com/app/controller/AdminController.java +41 -0
  110. package/tools/templates/modules/admin/backend/java-spring/backend/src/main/java/com/app/entity/User.java +55 -0
  111. package/tools/templates/modules/admin/backend/java-spring/backend/src/main/java/com/app/repository/UserRepository.java +8 -0
  112. package/tools/templates/modules/admin/frontend/svelte/frontend/src/routes/dashboard/+page.svelte +93 -0
  113. package/tools/templates/modules/auth/backend/node-express/backend/src/middleware/auth.ts +42 -0
  114. package/tools/templates/modules/auth/frontend/svelte/frontend/src/hooks.client.ts +3 -0
  115. package/tools/templates/modules/auth/frontend/svelte/frontend/src/lib/auth.ts +104 -0
  116. package/tools/templates/modules/auth/frontend/svelte/frontend/src/routes/callback/+page.svelte +18 -0
  117. package/tools/templates/modules/auth/frontend/svelte/frontend/src/routes/login/+page.svelte +12 -0
  118. package/tools/templates/modules/chatbot/backend/node-express/backend/src/index.ts.ejs +69 -0
  119. package/tools/templates/modules/chatbot/backend/node-express/backend/src/routes/chatbot.ts.ejs +37 -0
  120. package/tools/templates/modules/chatbot/backend/node-express/backend/src/services/chatbotService.ts +124 -0
  121. package/tools/templates/modules/chatbot/backend/python-fastapi/backend/app/main.py.ejs +69 -0
  122. package/tools/templates/modules/chatbot/backend/python-fastapi/backend/app/routes/chatbot.py +38 -0
  123. package/tools/templates/modules/chatbot/backend/python-fastapi/backend/app/services/chatbot_service.py +123 -0
  124. package/tools/templates/modules/chatbot/backend/python-fastapi/backend/requirements.txt +1 -0
  125. package/tools/templates/modules/chatbot/frontend/react/frontend/src/App.jsx.ejs +74 -0
  126. package/tools/templates/modules/chatbot/frontend/react/frontend/src/components/Chatbot.css +198 -0
  127. package/tools/templates/modules/chatbot/frontend/react/frontend/src/components/Chatbot.jsx +113 -0
  128. package/tools/templates/modules/contact/backend/java-spring/backend/src/main/java/com/app/controller/ContactController.java +29 -0
  129. package/tools/templates/modules/contact/backend/java-spring/backend/src/main/java/com/app/entity/ContactMessage.java +66 -0
  130. package/tools/templates/modules/contact/backend/java-spring/backend/src/main/java/com/app/repository/ContactMessageRepository.java +8 -0
  131. package/tools/templates/modules/contact/backend/java-spring/backend/src/main/resources/db/migration/V2__contact.sql +7 -0
  132. package/tools/templates/modules/contact/frontend/svelte/frontend/src/routes/contact/+page.svelte +80 -0
  133. package/tools/templates/modules/payments/backend/java-spring/backend/src/main/java/com/app/controller/PaymentController.java +69 -0
  134. package/tools/templates/modules/payments/backend/node-express/backend/src/routes/payments.ts +30 -0
  135. package/tools/templates/modules/payments/backend/node-express/backend/src/routes/webhook.ts +36 -0
  136. package/tools/templates/modules/payments/frontend/svelte/frontend/src/lib/payments.ts +28 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Colby Leed
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,364 @@
1
+ # leedstack
2
+
3
+ > One-command scaffolder for full-stack web applications with pluggable stacks and modern defaults.
4
+
5
+ Generate production-ready full-stack applications in seconds with your choice of frontend, backend, database, and optional modules. The recommended default is React + Go (Echo) with Postgres.
6
+
7
+ ## Features
8
+
9
+ - **60+ Stack Combinations**: Mix and match your preferred technologies
10
+ - **âŔ” Lightning Fast**: From zero to coding in <30 seconds with `make setup`
11
+ - **ðŸŔ€ Production-Ready**: Docker, CI/CD, testing, monitoring - all included
12
+ - **🧪 Automated Testing**: Vitest with example tests, coverage, and test UI
13
+ - **Ć°Åøā€ā€ž CI/CD Pipeline**: GitHub Actions workflow for automated testing and deployment
14
+ - **🐳 Docker Support**: Multi-stage builds for optimized production images
15
+ - **Ć°Åøā€œÅ  Monitoring**: Health checks, memory tracking, K8s-compatible endpoints
16
+ - **Optimized Performance**: HMR <50ms, builds 20-40x faster with esbuild
17
+ - **Zero Memory Leaks**: Proper cleanup in all components and graceful shutdown
18
+ - **Most Popular Stacks**: React, Vue, Next.js, Python/FastAPI, Node/Express, and more
19
+ - **Auto-Configured Connectivity**: Frontend and backend pre-wired with correct ports and CORS
20
+ - **Modern Defaults**: SSR, code-splitting, tree-shaking, strict types
21
+ - **AI Chatbot Module**: Works out-of-box, upgrades with OpenAI/Anthropic API key
22
+ - **Auth0 Integration**: OIDC/PKCE flow with JWT validation
23
+ - **Stripe Payments**: Checkout + webhook handling
24
+ - **Code Quality Tools**: ESLint, Prettier, Error Boundaries pre-configured
25
+ - **Type-Safe**: TypeScript for frontends and Node backend
26
+
27
+ ## Free vs Pro (Planned)
28
+
29
+ The npm package will always include the core scaffolding and base stacks.
30
+ Pro will unlock premium modules and templates (Auth, Payments, Admin, Chatbot, deployment presets).
31
+
32
+ **Pricing (planned)**: one-time purchase for Pro (no subscription).
33
+ **Licensing (planned)**: Pro access will use a simple license key file (e.g. `~/.leedstackrc`) with no heavy DRM.
34
+
35
+ FAQ: Will there be a subscription later? Possibly for updates and new templates, but the initial plan is a one-time purchase.
36
+
37
+ ### Pro Module Compatibility (Current)
38
+
39
+ Frontends:
40
+
41
+ | Module | React | Vue | Next.js | Svelte | Angular |
42
+ | --- | --- | --- | --- | --- | --- |
43
+ | Auth | — | — | — | āœ“ | — |
44
+ | Payments | — | — | — | āœ“ | — |
45
+ | Admin | — | — | — | āœ“ | — |
46
+ | Contact | — | — | — | āœ“ | — |
47
+ | Chatbot | āœ“ | — | — | — | — |
48
+
49
+ Backends:
50
+
51
+ | Module | node-express | python-fastapi | java-spring | go-echo |
52
+ | --- | --- | --- | --- | --- |
53
+ | Auth | āœ“ | — | āœ“ | — |
54
+ | Payments | āœ“ | — | āœ“ | — |
55
+ | Admin | — | — | āœ“ | — |
56
+ | Contact | — | — | āœ“ | — |
57
+ | Chatbot | āœ“ | āœ“ | — | — |
58
+
59
+ If your selected stack isn't listed above, that module will be unavailable until we add support.
60
+
61
+ ### Pro Templates (ZIP Install)
62
+
63
+ If you purchase the Pro templates ZIP, install it like this:
64
+
65
+ ```bash
66
+ # Create the local templates folder
67
+ mkdir -p ~/.leedstack/templates
68
+
69
+ # Unzip the download into that folder (replace the zip path)
70
+ unzip /path/to/leedstack-pro-templates.zip -d ~/.leedstack/templates
71
+ ```
72
+
73
+ TODO: Add `leedstack login` and automated template downloads from a private registry.
74
+
75
+ ## Quick Start
76
+
77
+ ```bash
78
+ npx leedstack my-app \
79
+ --frontend react \
80
+ --backend go-echo \
81
+ --db postgres
82
+ ```
83
+
84
+ Then follow the printed instructions to start your app!
85
+
86
+ ## âŔ” Fastest Setup
87
+
88
+ ```bash
89
+ npx leedstack my-app --frontend react --backend go-echo --db postgres
90
+
91
+ cd my-app
92
+ make setup # Installs everything + starts database (parallel)
93
+ make dev # Start development servers
94
+ ```
95
+
96
+ **Total time: ~30 seconds to fully operational!** ðŸŔ€
97
+
98
+ See [PERFORMANCE.md](./PERFORMANCE.md) for optimization details.
99
+
100
+ ## 💰 Deployment Options
101
+
102
+ **Monorepo (Simple):**
103
+ - Deploy everything together: ~$5-15/month
104
+ - Best for: MVPs, small teams, rapid development
105
+
106
+ **Separate Repos (Cost Optimized):**
107
+ - Deploy frontend and backend separately: **$0/month** possible!
108
+ - Frontend: Vercel/Netlify/Cloudflare (FREE)
109
+ - Backend: Fly.io/Railway (FREE tiers)
110
+ - Database: Supabase/PlanetScale (FREE)
111
+ - Best for: Maximizing free tiers, independent scaling
112
+
113
+ **Split your monorepo:**
114
+ ```bash
115
+ ./scripts/split-repos.sh
116
+ ```
117
+
118
+ See [DEPLOYMENT_STRATEGIES.md](./DEPLOYMENT_STRATEGIES.md) for complete guide.
119
+
120
+ ## Supported Stacks
121
+
122
+ ### Frontends (5 options)
123
+ - **react** - Vite + React 19 (most popular!)
124
+ - **vue** - Vue 3.5 with Vite (lightweight and fast)
125
+ - **nextjs** - Next.js 15 (React with SSR/SSG)
126
+ - **svelte** - SvelteKit 5.x (innovative and performant)
127
+ - **angular** - Angular ≄19.0.0 (enterprise-ready)
128
+
129
+ ### Backends (4 options)
130
+ - **go-echo** - Go 1.22+ with Echo framework (high performance, recommended)
131
+ - **node-express** - TypeScript + Express 5.x, Node 20+ (JavaScript ecosystem)
132
+ - **python-fastapi** - Python 3.11+ with FastAPI (great for AI/ML integration)
133
+ - **java-spring** - Spring Boot 3.3.x, Maven, Java 21 LTS (enterprise standard)
134
+
135
+ ### Databases
136
+ - **postgres** - PostgreSQL 16+
137
+ - **mysql** - MySQL 8+
138
+ - **mongodb** - MongoDB 7+
139
+
140
+ ### Optional Modules
141
+ - **--auth auth0** - Auth0 OIDC authentication
142
+ - **--payments stripe** - Stripe Checkout integration
143
+ - **contact** - Contact form with DB persistence
144
+ - **admin** - Protected admin dashboard with stats
145
+ - **chatbot** - AI chatbot (works out-of-box, upgrades with OpenAI/Anthropic API key)
146
+
147
+ ## Usage
148
+
149
+ ```bash
150
+ npx leedstack <appName> \
151
+ --frontend <react|vue|nextjs|svelte|angular> \
152
+ --backend <node-express|python-fastapi|java-spring|go-echo> \
153
+ --db <postgres|mysql|mongodb> \
154
+ [--auth auth0|none] \
155
+ [--payments stripe|none] \
156
+ [contact] [admin]
157
+ ```
158
+
159
+ ### Options
160
+
161
+ - `-f, --frontend <type>` (required) - Frontend framework
162
+ - `-b, --backend <type>` (required) - Backend stack
163
+ - `--db <type>` (required) - Database
164
+ - `--auth <type>` - Authentication (default: none)
165
+ - `--payments <type>` - Payments (default: none)
166
+ - Trailing arguments: Additional modules (`contact`, `admin`, `chatbot`)
167
+
168
+ ## Examples
169
+
170
+ ### Modern Python + React Stack with AI Chatbot
171
+ ```bash
172
+ npx leedstack my-saas \
173
+ --frontend react \
174
+ --backend python-fastapi \
175
+ --db postgres \
176
+ --auth auth0 \
177
+ --payments stripe \
178
+ contact admin chatbot
179
+ ```
180
+
181
+ ### Recommended Default: React + Go + Postgres
182
+ ```bash
183
+ npx leedstack my-app \
184
+ --frontend react \
185
+ --backend go-echo \
186
+ --db postgres
187
+ ```
188
+
189
+ ### Vue + Node.js Blog
190
+ ```bash
191
+ npx leedstack blog \
192
+ --frontend vue \
193
+ --backend node-express \
194
+ --db mongodb \
195
+ chatbot
196
+ ```
197
+
198
+ ### Next.js E-commerce
199
+ ```bash
200
+ npx leedstack shop \
201
+ --frontend nextjs \
202
+ --backend node-express \
203
+ --db postgres \
204
+ --payments stripe
205
+
206
+ ```
207
+
208
+ ### Enterprise Java Stack
209
+ ```bash
210
+ npx leedstack enterprise \
211
+ --frontend angular \
212
+ --backend java-spring \
213
+ --db postgres \
214
+ --auth auth0 \
215
+ admin
216
+ ```
217
+
218
+ ## Generated Project Structure
219
+
220
+ ```
221
+ my-app/
222
+ Ć¢ā€Å“Ć¢ā€ā‚¬Ć¢ā€ā‚¬ docker-compose.yml # Database container
223
+ Ć¢ā€Å“Ć¢ā€ā‚¬Ć¢ā€ā‚¬ README.md # Project-specific docs
224
+ Ć¢ā€Å“Ć¢ā€ā‚¬Ć¢ā€ā‚¬ .env.example # Environment template
225
+ Ć¢ā€Å“Ć¢ā€ā‚¬Ć¢ā€ā‚¬ frontend/ # Frontend app
226
+ Ć¢ā€ā€š Ć¢ā€Å“Ć¢ā€ā‚¬Ć¢ā€ā‚¬ src/
227
+ Ć¢ā€ā€š Ć¢ā€Å“Ć¢ā€ā‚¬Ć¢ā€ā‚¬ package.json
228
+ Ć¢ā€ā€š Ć¢ā€ā€Ć¢ā€ā‚¬Ć¢ā€ā‚¬ .env.example
229
+ Ć¢ā€ā€Ć¢ā€ā‚¬Ć¢ā€ā‚¬ backend/ # Backend API
230
+ Ć¢ā€Å“Ć¢ā€ā‚¬Ć¢ā€ā‚¬ src/
231
+ Ć¢ā€ā€Ć¢ā€ā‚¬Ć¢ā€ā‚¬ .env.example
232
+ ```
233
+
234
+ ## What's Included
235
+
236
+ ### Base Features
237
+ - Docker Compose for database
238
+ - Health endpoints (`/actuator/health` or `/health`)
239
+ - CORS configuration for development
240
+ - Environment variable management
241
+ - Production-ready defaults
242
+
243
+ ### With Auth0 (`--auth auth0`)
244
+ - Frontend: Login/logout flow, token management
245
+ - Backend: JWT validation via JWKS, protected routes
246
+ - Admin scope enforcement for `/api/admin/**` endpoints
247
+
248
+ ### With Stripe (`--payments stripe`)
249
+ - Create Checkout sessions
250
+ - Webhook signature verification
251
+ - Payment success handling
252
+
253
+ ### With Contact Module
254
+ - Contact form (name, email, message)
255
+ - Database persistence
256
+ - `/api/contact` endpoint
257
+
258
+ ### With Admin Module
259
+ - Protected dashboard (requires `admin` scope)
260
+ - User and contact stats
261
+ - `/api/admin/stats` endpoint
262
+
263
+ ## Technology Choices
264
+
265
+ ### Version Policy
266
+ - Pin majors, float minors/patches using `^` (npm) or latest minor (Maven/Go)
267
+ - Enforce minimum runtimes via `engines` field
268
+
269
+ ### Security
270
+ - JWT validation via JWKS (no custom crypto)
271
+ - CORS configurable per environment
272
+ - Secrets via environment variables only
273
+ - Admin routes protected by scope/permission
274
+
275
+ ### Efficiency
276
+ - **Frontend**: SSR, code-splitting, lazy-loaded admin, minimal deps
277
+ - **Backend**: JSON-only APIs, no view engines
278
+ - **Docker**: Multi-stage builds, distroless/alpine images
279
+
280
+ ## Requirements
281
+
282
+ - **Node.js** ≄20.0.0
283
+ - **Java** 21 LTS (for java-spring backend)
284
+ - **Go** ≄1.22 (for go-echo backend)
285
+ - **Docker** (for running databases)
286
+ - **Maven** (for java-spring backend)
287
+
288
+ ## Development
289
+
290
+ ### Running Generated Projects
291
+
292
+ 1. **Start database**:
293
+ ```bash
294
+ docker compose up -d
295
+ ```
296
+
297
+ 2. **Backend**:
298
+ ```bash
299
+ cd backend
300
+ # Java Spring
301
+ mvn spring-boot:run
302
+
303
+ # Node Express
304
+ npm install && npm run dev
305
+
306
+ # Go Echo
307
+ go run ./cmd/server
308
+ ```
309
+
310
+ 3. **Frontend**:
311
+ ```bash
312
+ cd frontend
313
+ cp .env.example .env
314
+ npm install
315
+ npm run dev
316
+ ```
317
+
318
+ ### Environment Setup
319
+
320
+ See the generated `README.md` in your project for specific Auth0 and Stripe configuration instructions.
321
+
322
+ ## Publishing to npm
323
+
324
+ If you want to publish this package:
325
+
326
+ 1. Update `package.json`:
327
+ - Change `name` if needed (must be unique on npm)
328
+ - Set your `author` name and email
329
+ - Update `repository`, `bugs`, `homepage` URLs
330
+
331
+ 2. Create npm account: https://www.npmjs.com/signup
332
+
333
+ 3. Login and publish:
334
+ ```bash
335
+ npm login
336
+ npm publish
337
+ ```
338
+
339
+ 4. Users can then run:
340
+ ```bash
341
+ npx leedstack my-app --frontend react --backend node-express --db postgres
342
+ ```
343
+
344
+ ## License
345
+
346
+ MIT (c) Colby Leed
347
+
348
+ ## Contributing
349
+
350
+ Issues and PRs welcome! Please ensure generated projects compile and run before submitting.
351
+
352
+ ## Support
353
+
354
+ - Report issues: https://github.com/CTLeed/leedstack/issues
355
+ - Documentation: https://github.com/CTLeed/leedstack
356
+
357
+
358
+
359
+
360
+
361
+
362
+
363
+
364
+
@@ -0,0 +1,277 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { Command } from 'commander';
4
+ import fs from 'fs-extra';
5
+ import path from 'path';
6
+ import { fileURLToPath } from 'url';
7
+ import ejs from 'ejs';
8
+ // Simple case converters
9
+ function paramCase(str) {
10
+ return str.replace(/([a-z])([A-Z])/g, '$1-$2')
11
+ .replace(/[\s_]+/g, '-')
12
+ .toLowerCase();
13
+ }
14
+
15
+ function pascalCase(str) {
16
+ return str.replace(/[-_\s]+(.)?/g, (_, c) => c ? c.toUpperCase() : '')
17
+ .replace(/^(.)/, (_, c) => c.toUpperCase());
18
+ }
19
+
20
+ const __filename = fileURLToPath(import.meta.url);
21
+ const __dirname = path.dirname(__filename);
22
+
23
+ const program = new Command();
24
+
25
+ program
26
+ .name('leedstack')
27
+ .version('3.1.0')
28
+ .description('Generate a full-stack web application with your choice of tech stack')
29
+ .argument('<appName>', 'Name of the application')
30
+ .requiredOption('-f, --frontend <type>', 'Frontend stack (react|vue|nextjs|svelte|angular)')
31
+ .requiredOption('-b, --backend <type>', 'Backend stack (node-express|python-fastapi|java-spring|go-echo)')
32
+ .requiredOption('--db <type>', 'Database (postgres|mysql|mongodb)')
33
+ .option('--auth <type>', 'Authentication (auth0|none)', 'none')
34
+ .option('--payments <type>', 'Payments (stripe|none)', 'none')
35
+ .addHelpText('after', `
36
+ Examples:
37
+ $ npx leedstack my-app --frontend react --backend python-fastapi --db postgres --auth auth0 --payments stripe contact admin
38
+ $ npx leedstack blog --frontend vue --backend node-express --db mongodb
39
+ $ npx leedstack shop --frontend nextjs --backend java-spring --db mysql --payments stripe
40
+
41
+ Supported Stacks:
42
+ Frontends: react (Vite + React 19), vue (Vue 3.5), nextjs (Next.js 15), svelte (SvelteKit 5.x), angular (Angular 19+)
43
+ Backends: node-express (Node 20+ + TypeScript), python-fastapi (Python 3.11+ FastAPI), java-spring (Java 21 + Maven), go-echo (Go 1.22+)
44
+ Databases: postgres (16+), mysql (8+), mongodb (7+)
45
+
46
+ Optional Modules:
47
+ --auth auth0 Auth0 OIDC authentication with JWT validation
48
+ --payments stripe Stripe Checkout + webhook integration
49
+ contact Contact form with database persistence
50
+ admin Protected admin dashboard (requires auth with 'admin' scope)
51
+ chatbot AI chatbot (works out-of-box, upgrades with OpenAI/Anthropic API key)
52
+
53
+ For more info: https://github.com/CTLeed/leedstack
54
+ `)
55
+ .action(async (appName, options, command) => {
56
+ const additionalModules = command.args.slice(1);
57
+
58
+ const validFrontends = ['react', 'vue', 'nextjs', 'svelte', 'angular'];
59
+ const validBackends = ['node-express', 'python-fastapi', 'java-spring', 'go-echo'];
60
+ const validDatabases = ['postgres', 'mysql', 'mongodb'];
61
+ const validAuth = ['auth0', 'none'];
62
+ const validPayments = ['stripe', 'none'];
63
+ const validModules = ['contact', 'admin', 'chatbot'];
64
+
65
+ // Validation
66
+ if (!validFrontends.includes(options.frontend)) {
67
+ console.error(`āŒ Invalid frontend: ${options.frontend}. Must be one of: ${validFrontends.join(', ')}`);
68
+ process.exit(1);
69
+ }
70
+ if (!validBackends.includes(options.backend)) {
71
+ console.error(`āŒ Invalid backend: ${options.backend}. Must be one of: ${validBackends.join(', ')}`);
72
+ process.exit(1);
73
+ }
74
+ if (!validDatabases.includes(options.db)) {
75
+ console.error(`āŒ Invalid database: ${options.db}. Must be one of: ${validDatabases.join(', ')}`);
76
+ process.exit(1);
77
+ }
78
+ if (!validAuth.includes(options.auth)) {
79
+ console.error(`āŒ Invalid auth: ${options.auth}. Must be one of: ${validAuth.join(', ')}`);
80
+ process.exit(1);
81
+ }
82
+ if (!validPayments.includes(options.payments)) {
83
+ console.error(`āŒ Invalid payments: ${options.payments}. Must be one of: ${validPayments.join(', ')}`);
84
+ process.exit(1);
85
+ }
86
+ for (const mod of additionalModules) {
87
+ if (!validModules.includes(mod)) {
88
+ console.error(`āŒ Invalid module: ${mod}. Must be one of: ${validModules.join(', ')}`);
89
+ process.exit(1);
90
+ }
91
+ }
92
+
93
+ const targetDir = path.resolve(process.cwd(), appName);
94
+
95
+ // Fail if target directory exists
96
+ if (await fs.pathExists(targetDir)) {
97
+ console.error(`āŒ Directory ${appName} already exists. Please choose a different name or remove the existing directory.`);
98
+ process.exit(1);
99
+ }
100
+
101
+ const appSlug = paramCase(appName);
102
+ const AppName = pascalCase(appName);
103
+
104
+ const modules = {
105
+ auth: options.auth !== 'none',
106
+ payments: options.payments !== 'none',
107
+ contact: additionalModules.includes('contact'),
108
+ admin: additionalModules.includes('admin'),
109
+ chatbot: additionalModules.includes('chatbot')
110
+ };
111
+
112
+ const frontendPorts = {
113
+ react: 5173,
114
+ vue: 5173,
115
+ svelte: 5173,
116
+ nextjs: 3000,
117
+ angular: 4200
118
+ };
119
+ const frontendPort = frontendPorts[options.frontend] || 5173;
120
+
121
+ const context = {
122
+ appName,
123
+ appSlug,
124
+ AppName,
125
+ frontend: options.frontend,
126
+ backend: options.backend,
127
+ db: options.db,
128
+ auth: options.auth,
129
+ payments: options.payments,
130
+ modules,
131
+ frontendPort
132
+ };
133
+
134
+ console.log(`\nšŸš€ Creating ${appName}...`);
135
+ console.log(` Frontend: ${options.frontend}`);
136
+ console.log(` Backend: ${options.backend}`);
137
+ console.log(` Database: ${options.db}`);
138
+ if (modules.auth) console.log(` Auth: ${options.auth}`);
139
+ if (modules.payments) console.log(` Payments: ${options.payments}`);
140
+ if (modules.contact) console.log(` āœ“ contact module`);
141
+ if (modules.admin) console.log(` āœ“ admin module`);
142
+ if (modules.chatbot) console.log(` āœ“ chatbot module`);
143
+ console.log('');
144
+
145
+ const warnings = [];
146
+ const templatesDir = path.resolve(__dirname, '..', 'tools', 'templates');
147
+
148
+ // Template resolution order
149
+ const templateLayers = [
150
+ { type: 'base', path: path.join(templatesDir, 'base') },
151
+ { type: 'frontend', path: path.join(templatesDir, 'frontend', options.frontend) },
152
+ { type: 'backend', path: path.join(templatesDir, 'backend', options.backend) },
153
+ { type: 'db', path: path.join(templatesDir, 'db', options.db, 'backend', options.backend) }
154
+ ];
155
+
156
+ // Add module layers
157
+ const moduleNames = [];
158
+ if (modules.auth) moduleNames.push('auth');
159
+ if (modules.payments) moduleNames.push('payments');
160
+ if (modules.contact) moduleNames.push('contact');
161
+ if (modules.admin) moduleNames.push('admin');
162
+ if (modules.chatbot) moduleNames.push('chatbot');
163
+
164
+ for (const modName of moduleNames) {
165
+ templateLayers.push({
166
+ type: `module-${modName}-frontend`,
167
+ path: path.join(templatesDir, 'modules', modName, 'frontend', options.frontend)
168
+ });
169
+ templateLayers.push({
170
+ type: `module-${modName}-backend`,
171
+ path: path.join(templatesDir, 'modules', modName, 'backend', options.backend)
172
+ });
173
+ }
174
+
175
+ // Process each layer
176
+ for (const layer of templateLayers) {
177
+ if (await fs.pathExists(layer.path)) {
178
+ await copyAndRenderTemplates(layer.path, targetDir, context);
179
+ } else {
180
+ const skipDbWarning = layer.type === 'db' && ['go-echo', 'python-fastapi'].includes(options.backend);
181
+ if (!skipDbWarning) {
182
+ warnings.push(`⚠ ${layer.type}: MISSING (path: ${layer.path})`);
183
+
184
+ // Generate stub
185
+ const stubPath = path.join(targetDir, `MISSING_${layer.type}.txt`);
186
+ await fs.writeFile(stubPath, `TODO: Missing template\nPath: ${layer.type}\nContract: Implement the documented endpoint/component signature.\n`);
187
+ }
188
+ }
189
+ }
190
+
191
+ console.log(`āœ… Project ${appName} created successfully!\n`);
192
+
193
+ if (warnings.length > 0) {
194
+ console.log('āš ļø Warnings:');
195
+ warnings.forEach(w => console.log(` ${w}`));
196
+ console.log('');
197
+ }
198
+
199
+ // Print next steps
200
+ console.log('šŸ“‹ Next steps:\n');
201
+ console.log('1. Start the database:');
202
+ console.log(` cd ${appName}`);
203
+ console.log(' docker compose up -d\n');
204
+
205
+ console.log('2. Set up environment variables:');
206
+ console.log(' cp .env.example .env');
207
+ console.log(' # Edit .env with your configuration\n');
208
+
209
+ console.log('3. Start the backend:');
210
+ console.log(' cd backend');
211
+ if (options.backend === 'java-spring') {
212
+ console.log(' mvn spring-boot:run');
213
+ } else if (options.backend === 'node-express') {
214
+ console.log(' npm install');
215
+ console.log(' npm run dev');
216
+ } else if (options.backend === 'go-echo') {
217
+ console.log(' go run ./cmd/server');
218
+ }
219
+ console.log('');
220
+
221
+ console.log('4. Start the frontend (in a new terminal):');
222
+ console.log(' cd frontend');
223
+ console.log(' cp .env.example .env');
224
+ console.log(' npm install');
225
+ console.log(' npm run dev');
226
+ console.log('');
227
+
228
+ if (modules.auth) {
229
+ console.log('5. Configure Auth0:');
230
+ console.log(' - Create a SPA app in Auth0');
231
+ console.log(' - Set Allowed Callback URLs: http://localhost:5173/callback');
232
+ console.log(' - Set Allowed Logout URLs: http://localhost:5173');
233
+ console.log(' - Set Allowed Web Origins: http://localhost:5173');
234
+ console.log(` - Create an API with Identifier: https://api.${appSlug}`);
235
+ console.log(' - Update .env files with Auth0 credentials\n');
236
+ }
237
+
238
+ if (modules.payments) {
239
+ console.log(`${modules.auth ? '6' : '5'}. Configure Stripe:`);
240
+ console.log(' - Set STRIPE_SECRET_KEY in backend .env');
241
+ console.log(' - Run: stripe listen --forward-to localhost:8080/stripe/webhook');
242
+ console.log(' - Set STRIPE_WEBHOOK_SECRET from the output\n');
243
+ }
244
+ });
245
+
246
+ async function copyAndRenderTemplates(srcDir, destDir, context) {
247
+ const items = await fs.readdir(srcDir, { withFileTypes: true });
248
+
249
+ for (const item of items) {
250
+ const srcPath = path.join(srcDir, item.name);
251
+ let destName = item.name;
252
+
253
+ // Remove .ejs extension if present
254
+ if (destName.endsWith('.ejs')) {
255
+ destName = destName.slice(0, -4);
256
+ }
257
+
258
+ const destPath = path.join(destDir, destName);
259
+
260
+ if (item.isDirectory()) {
261
+ await fs.ensureDir(destPath);
262
+ await copyAndRenderTemplates(srcPath, destPath, context);
263
+ } else {
264
+ // Check if it's an EJS template
265
+ if (item.name.endsWith('.ejs')) {
266
+ const template = await fs.readFile(srcPath, 'utf-8');
267
+ const rendered = ejs.render(template, context);
268
+ await fs.writeFile(destPath, rendered);
269
+ } else {
270
+ // Copy as-is
271
+ await fs.copy(srcPath, destPath);
272
+ }
273
+ }
274
+ }
275
+ }
276
+
277
+ program.parse();