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.
- package/LICENSE +21 -0
- package/README.md +364 -0
- package/bin/create-stack.js +277 -0
- package/package.json +60 -0
- package/tools/templates/backend/go-echo/backend/.env.example +10 -0
- package/tools/templates/backend/go-echo/backend/cmd/server/main.go.ejs +57 -0
- package/tools/templates/backend/go-echo/backend/go.mod.ejs +10 -0
- package/tools/templates/backend/go-echo/backend/internal/handlers/example.go +15 -0
- package/tools/templates/backend/go-echo/backend/internal/handlers/health.go +13 -0
- package/tools/templates/backend/java-spring/backend/.env.example +10 -0
- package/tools/templates/backend/java-spring/backend/pom.xml.ejs +64 -0
- package/tools/templates/backend/java-spring/backend/src/main/java/com/app/Application.java.ejs +11 -0
- package/tools/templates/backend/java-spring/backend/src/main/java/com/app/config/SecurityConfig.java.ejs +64 -0
- package/tools/templates/backend/java-spring/backend/src/main/java/com/app/controller/ExampleController.java +19 -0
- package/tools/templates/backend/java-spring/backend/src/main/java/com/app/controller/HealthController.java +15 -0
- package/tools/templates/backend/java-spring/backend/src/main/resources/application.yml.ejs +20 -0
- package/tools/templates/backend/node-express/backend/.env.example +10 -0
- package/tools/templates/backend/node-express/backend/.eslintrc.json +21 -0
- package/tools/templates/backend/node-express/backend/.prettierrc +10 -0
- package/tools/templates/backend/node-express/backend/Dockerfile +52 -0
- package/tools/templates/backend/node-express/backend/README.md +68 -0
- package/tools/templates/backend/node-express/backend/package.json.ejs +37 -0
- package/tools/templates/backend/node-express/backend/src/index.ts.ejs +75 -0
- package/tools/templates/backend/node-express/backend/src/routes/health.ts +54 -0
- package/tools/templates/backend/node-express/backend/tsconfig.json +17 -0
- package/tools/templates/backend/python-fastapi/backend/.env.example +18 -0
- package/tools/templates/backend/python-fastapi/backend/README.md +73 -0
- package/tools/templates/backend/python-fastapi/backend/app/__init__.py +1 -0
- package/tools/templates/backend/python-fastapi/backend/app/main.py.ejs +68 -0
- package/tools/templates/backend/python-fastapi/backend/requirements.txt.ejs +22 -0
- package/tools/templates/base/.dockerignore +16 -0
- package/tools/templates/base/.env.example +31 -0
- package/tools/templates/base/.github/workflows/ci.yml.ejs +124 -0
- package/tools/templates/base/.github/workflows/deploy-separate.yml.example +144 -0
- package/tools/templates/base/.vscode/extensions.json +17 -0
- package/tools/templates/base/.vscode/settings.json +49 -0
- package/tools/templates/base/Makefile +98 -0
- package/tools/templates/base/README.md.ejs +118 -0
- package/tools/templates/base/docker-compose.yml.ejs +49 -0
- package/tools/templates/base/package.json.ejs +30 -0
- package/tools/templates/base/scripts/split-repos.sh +189 -0
- package/tools/templates/db/postgres/backend/java-spring/backend/pom.xml.ejs +81 -0
- package/tools/templates/db/postgres/backend/java-spring/backend/src/main/resources/application.yml.ejs +39 -0
- package/tools/templates/db/postgres/backend/java-spring/backend/src/main/resources/db/migration/V1__init.sql +17 -0
- package/tools/templates/db/postgres/backend/node-express/backend/.env.example +10 -0
- package/tools/templates/db/postgres/backend/node-express/backend/package.json.ejs +32 -0
- package/tools/templates/db/postgres/backend/node-express/backend/prisma/schema.prisma.ejs +39 -0
- package/tools/templates/frontend/angular/frontend/.env.example +9 -0
- package/tools/templates/frontend/angular/frontend/angular.json +66 -0
- package/tools/templates/frontend/angular/frontend/package.json.ejs +31 -0
- package/tools/templates/frontend/angular/frontend/src/app/app.component.ts +30 -0
- package/tools/templates/frontend/angular/frontend/src/app/app.routes.ts +18 -0
- package/tools/templates/frontend/angular/frontend/src/app/components/home.component.ts +24 -0
- package/tools/templates/frontend/angular/frontend/src/app/services/api.service.ts +48 -0
- package/tools/templates/frontend/angular/frontend/src/favicon.ico +1 -0
- package/tools/templates/frontend/angular/frontend/src/index.html +13 -0
- package/tools/templates/frontend/angular/frontend/src/main.ts +10 -0
- package/tools/templates/frontend/angular/frontend/src/styles.css +31 -0
- package/tools/templates/frontend/angular/frontend/tsconfig.app.json +9 -0
- package/tools/templates/frontend/angular/frontend/tsconfig.json +27 -0
- package/tools/templates/frontend/nextjs/frontend/.env.example +9 -0
- package/tools/templates/frontend/nextjs/frontend/next.config.js +37 -0
- package/tools/templates/frontend/nextjs/frontend/package.json.ejs +25 -0
- package/tools/templates/frontend/nextjs/frontend/src/app/globals.css +31 -0
- package/tools/templates/frontend/nextjs/frontend/src/app/layout.tsx +36 -0
- package/tools/templates/frontend/nextjs/frontend/src/app/page.tsx +19 -0
- package/tools/templates/frontend/nextjs/frontend/src/lib/api.ts +45 -0
- package/tools/templates/frontend/nextjs/frontend/tsconfig.json +27 -0
- package/tools/templates/frontend/react/frontend/.env.example +9 -0
- package/tools/templates/frontend/react/frontend/.eslintrc.json +32 -0
- package/tools/templates/frontend/react/frontend/.prettierrc +10 -0
- package/tools/templates/frontend/react/frontend/Dockerfile +37 -0
- package/tools/templates/frontend/react/frontend/README.md +54 -0
- package/tools/templates/frontend/react/frontend/index.html +13 -0
- package/tools/templates/frontend/react/frontend/nginx.conf +35 -0
- package/tools/templates/frontend/react/frontend/package.json.ejs +41 -0
- package/tools/templates/frontend/react/frontend/public/vite.svg +4 -0
- package/tools/templates/frontend/react/frontend/src/App.css +65 -0
- package/tools/templates/frontend/react/frontend/src/App.jsx +41 -0
- package/tools/templates/frontend/react/frontend/src/assets/react.svg +7 -0
- package/tools/templates/frontend/react/frontend/src/components/ErrorBoundary.jsx +62 -0
- package/tools/templates/frontend/react/frontend/src/components/Home.jsx +58 -0
- package/tools/templates/frontend/react/frontend/src/components/__tests__/Home.test.jsx +74 -0
- package/tools/templates/frontend/react/frontend/src/index.css +31 -0
- package/tools/templates/frontend/react/frontend/src/lib/api.js +42 -0
- package/tools/templates/frontend/react/frontend/src/lib/env.js +58 -0
- package/tools/templates/frontend/react/frontend/src/main.jsx +16 -0
- package/tools/templates/frontend/react/frontend/src/setupTests.js +8 -0
- package/tools/templates/frontend/react/frontend/vite.config.js +30 -0
- package/tools/templates/frontend/react/frontend/vitest.config.js +20 -0
- package/tools/templates/frontend/svelte/frontend/.env.example +9 -0
- package/tools/templates/frontend/svelte/frontend/package.json.ejs +21 -0
- package/tools/templates/frontend/svelte/frontend/src/app.html +12 -0
- package/tools/templates/frontend/svelte/frontend/src/lib/api.ts +45 -0
- package/tools/templates/frontend/svelte/frontend/src/routes/+layout.svelte +56 -0
- package/tools/templates/frontend/svelte/frontend/src/routes/+page.svelte +20 -0
- package/tools/templates/frontend/svelte/frontend/static/favicon.png +1 -0
- package/tools/templates/frontend/svelte/frontend/svelte.config.js +10 -0
- package/tools/templates/frontend/svelte/frontend/vite.config.js +9 -0
- package/tools/templates/frontend/vue/frontend/.env.example +9 -0
- package/tools/templates/frontend/vue/frontend/index.html +13 -0
- package/tools/templates/frontend/vue/frontend/package.json.ejs +20 -0
- package/tools/templates/frontend/vue/frontend/src/App.vue +60 -0
- package/tools/templates/frontend/vue/frontend/src/lib/api.js +42 -0
- package/tools/templates/frontend/vue/frontend/src/main.js +33 -0
- package/tools/templates/frontend/vue/frontend/src/views/ApiTest.vue +39 -0
- package/tools/templates/frontend/vue/frontend/src/views/Home.vue +30 -0
- package/tools/templates/frontend/vue/frontend/vite.config.js +9 -0
- package/tools/templates/modules/admin/backend/java-spring/backend/src/main/java/com/app/controller/AdminController.java +41 -0
- package/tools/templates/modules/admin/backend/java-spring/backend/src/main/java/com/app/entity/User.java +55 -0
- package/tools/templates/modules/admin/backend/java-spring/backend/src/main/java/com/app/repository/UserRepository.java +8 -0
- package/tools/templates/modules/admin/frontend/svelte/frontend/src/routes/dashboard/+page.svelte +93 -0
- package/tools/templates/modules/auth/backend/node-express/backend/src/middleware/auth.ts +42 -0
- package/tools/templates/modules/auth/frontend/svelte/frontend/src/hooks.client.ts +3 -0
- package/tools/templates/modules/auth/frontend/svelte/frontend/src/lib/auth.ts +104 -0
- package/tools/templates/modules/auth/frontend/svelte/frontend/src/routes/callback/+page.svelte +18 -0
- package/tools/templates/modules/auth/frontend/svelte/frontend/src/routes/login/+page.svelte +12 -0
- package/tools/templates/modules/chatbot/backend/node-express/backend/src/index.ts.ejs +69 -0
- package/tools/templates/modules/chatbot/backend/node-express/backend/src/routes/chatbot.ts.ejs +37 -0
- package/tools/templates/modules/chatbot/backend/node-express/backend/src/services/chatbotService.ts +124 -0
- package/tools/templates/modules/chatbot/backend/python-fastapi/backend/app/main.py.ejs +69 -0
- package/tools/templates/modules/chatbot/backend/python-fastapi/backend/app/routes/chatbot.py +38 -0
- package/tools/templates/modules/chatbot/backend/python-fastapi/backend/app/services/chatbot_service.py +123 -0
- package/tools/templates/modules/chatbot/backend/python-fastapi/backend/requirements.txt +1 -0
- package/tools/templates/modules/chatbot/frontend/react/frontend/src/App.jsx.ejs +74 -0
- package/tools/templates/modules/chatbot/frontend/react/frontend/src/components/Chatbot.css +198 -0
- package/tools/templates/modules/chatbot/frontend/react/frontend/src/components/Chatbot.jsx +113 -0
- package/tools/templates/modules/contact/backend/java-spring/backend/src/main/java/com/app/controller/ContactController.java +29 -0
- package/tools/templates/modules/contact/backend/java-spring/backend/src/main/java/com/app/entity/ContactMessage.java +66 -0
- package/tools/templates/modules/contact/backend/java-spring/backend/src/main/java/com/app/repository/ContactMessageRepository.java +8 -0
- package/tools/templates/modules/contact/backend/java-spring/backend/src/main/resources/db/migration/V2__contact.sql +7 -0
- package/tools/templates/modules/contact/frontend/svelte/frontend/src/routes/contact/+page.svelte +80 -0
- package/tools/templates/modules/payments/backend/java-spring/backend/src/main/java/com/app/controller/PaymentController.java +69 -0
- package/tools/templates/modules/payments/backend/node-express/backend/src/routes/payments.ts +30 -0
- package/tools/templates/modules/payments/backend/node-express/backend/src/routes/webhook.ts +36 -0
- package/tools/templates/modules/payments/frontend/svelte/frontend/src/lib/payments.ts +28 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
|
|
3
|
+
const router = Router();
|
|
4
|
+
|
|
5
|
+
interface HealthStatus {
|
|
6
|
+
status: 'UP' | 'DOWN';
|
|
7
|
+
timestamp: string;
|
|
8
|
+
uptime: number;
|
|
9
|
+
environment: string;
|
|
10
|
+
version: string;
|
|
11
|
+
checks?: {
|
|
12
|
+
database?: 'UP' | 'DOWN';
|
|
13
|
+
memory?: {
|
|
14
|
+
used: number;
|
|
15
|
+
total: number;
|
|
16
|
+
percentage: number;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
router.get('/', (req, res) => {
|
|
22
|
+
const health: HealthStatus = {
|
|
23
|
+
status: 'UP',
|
|
24
|
+
timestamp: new Date().toISOString(),
|
|
25
|
+
uptime: process.uptime(),
|
|
26
|
+
environment: process.env.NODE_ENV || 'development',
|
|
27
|
+
version: process.env.npm_package_version || '1.0.0',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// Add memory usage
|
|
31
|
+
const memUsage = process.memoryUsage();
|
|
32
|
+
health.checks = {
|
|
33
|
+
memory: {
|
|
34
|
+
used: Math.round(memUsage.heapUsed / 1024 / 1024), // MB
|
|
35
|
+
total: Math.round(memUsage.heapTotal / 1024 / 1024), // MB
|
|
36
|
+
percentage: Math.round((memUsage.heapUsed / memUsage.heapTotal) * 100),
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
res.json(health);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Liveness probe (K8s compatible)
|
|
44
|
+
router.get('/live', (req, res) => {
|
|
45
|
+
res.json({ status: 'UP' });
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// Readiness probe (K8s compatible)
|
|
49
|
+
router.get('/ready', (req, res) => {
|
|
50
|
+
// Add database check here if needed
|
|
51
|
+
res.json({ status: 'UP' });
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
export default router;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"outDir": "./dist",
|
|
8
|
+
"rootDir": "./src",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"resolveJsonModule": true
|
|
14
|
+
},
|
|
15
|
+
"include": ["src/**/*"],
|
|
16
|
+
"exclude": ["node_modules"]
|
|
17
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
APP_PORT=8080
|
|
2
|
+
FRONTEND_URL=http://localhost:<%= frontendPort %>
|
|
3
|
+
FRONTEND_URL=http://localhost:5173
|
|
4
|
+
<% if (modules.auth) { -%>
|
|
5
|
+
AUTH0_DOMAIN=your-tenant.us.auth0.com
|
|
6
|
+
AUTH0_AUDIENCE=https://api.<%= appSlug %>
|
|
7
|
+
<% } -%>
|
|
8
|
+
<% if (modules.payments) { -%>
|
|
9
|
+
STRIPE_SECRET_KEY=sk_test_xxx
|
|
10
|
+
STRIPE_WEBHOOK_SECRET=whsec_xxx
|
|
11
|
+
<% } -%>
|
|
12
|
+
<% if (db === 'postgres') { -%>
|
|
13
|
+
DATABASE_URL=postgresql://<%= appSlug %>:password@localhost:5432/<%= appSlug %>_dev
|
|
14
|
+
<% } else if (db === 'mysql') { -%>
|
|
15
|
+
DATABASE_URL=mysql+pymysql://<%= appSlug %>:password@localhost:3306/<%= appSlug %>_dev
|
|
16
|
+
<% } else { -%>
|
|
17
|
+
DATABASE_URL=mongodb://localhost:27017/<%= appSlug %>_dev
|
|
18
|
+
<% } -%>
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# <%= AppName %> - Backend
|
|
2
|
+
|
|
3
|
+
Python + FastAPI backend.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Create virtual environment
|
|
9
|
+
python -m venv venv
|
|
10
|
+
|
|
11
|
+
# Activate virtual environment
|
|
12
|
+
# On Windows:
|
|
13
|
+
venv\Scripts\activate
|
|
14
|
+
# On macOS/Linux:
|
|
15
|
+
source venv/bin/activate
|
|
16
|
+
|
|
17
|
+
# Install dependencies
|
|
18
|
+
pip install -r requirements.txt
|
|
19
|
+
|
|
20
|
+
# Set up environment
|
|
21
|
+
cp .env.example .env
|
|
22
|
+
|
|
23
|
+
# Start development server
|
|
24
|
+
python -m app.main
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Server runs on http://localhost:8080
|
|
28
|
+
|
|
29
|
+
API documentation available at http://localhost:8080/docs
|
|
30
|
+
|
|
31
|
+
## Available Commands
|
|
32
|
+
|
|
33
|
+
- `python -m app.main` - Start development server
|
|
34
|
+
- `uvicorn app.main:app --reload` - Alternative dev server command
|
|
35
|
+
- `uvicorn app.main:app --host 0.0.0.0 --port 8080` - Production server
|
|
36
|
+
|
|
37
|
+
## Environment Variables
|
|
38
|
+
|
|
39
|
+
See `.env.example` for required variables:
|
|
40
|
+
|
|
41
|
+
- `APP_PORT` - Server port (default: 8080)
|
|
42
|
+
- `DATABASE_URL` - Database connection string
|
|
43
|
+
<% if (modules.auth) { -%>
|
|
44
|
+
- `AUTH0_DOMAIN` - Auth0 domain
|
|
45
|
+
- `AUTH0_AUDIENCE` - Auth0 API audience
|
|
46
|
+
<% } -%>
|
|
47
|
+
|
|
48
|
+
## API Routes
|
|
49
|
+
|
|
50
|
+
FastAPI automatically generates interactive API docs at `/docs`.
|
|
51
|
+
|
|
52
|
+
Available endpoints:
|
|
53
|
+
- `GET /health` - Health check endpoint
|
|
54
|
+
- `GET /api/example` - Example API route
|
|
55
|
+
<% if (modules.contact) { -%>
|
|
56
|
+
- `POST /api/contact` - Submit contact form
|
|
57
|
+
<% } -%>
|
|
58
|
+
<% if (modules.admin) { -%>
|
|
59
|
+
- `GET /api/admin/stats` - Admin statistics (requires auth)
|
|
60
|
+
<% } -%>
|
|
61
|
+
|
|
62
|
+
## Tech Stack
|
|
63
|
+
|
|
64
|
+
- **Python ≥3.11** - Runtime
|
|
65
|
+
- **FastAPI** - Modern web framework
|
|
66
|
+
- **Uvicorn** - ASGI server
|
|
67
|
+
- **Pydantic** - Data validation
|
|
68
|
+
<% if (db === 'postgres' || db === 'mysql') { -%>
|
|
69
|
+
- **SQLAlchemy** - ORM
|
|
70
|
+
- **Alembic** - Database migrations
|
|
71
|
+
<% } else if (db === 'mongodb') { -%>
|
|
72
|
+
- **Motor** - Async MongoDB driver
|
|
73
|
+
<% } -%>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# FastAPI app package
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
from fastapi import FastAPI
|
|
2
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
3
|
+
<% if (modules.auth) { -%>
|
|
4
|
+
from app.middleware.auth import AuthMiddleware
|
|
5
|
+
<% } -%>
|
|
6
|
+
import os
|
|
7
|
+
from dotenv import load_dotenv
|
|
8
|
+
|
|
9
|
+
load_dotenv()
|
|
10
|
+
|
|
11
|
+
app = FastAPI(title="<%= AppName %> API")
|
|
12
|
+
|
|
13
|
+
# CORS configuration - allow only the configured frontend URL
|
|
14
|
+
allowed_origins = [os.getenv("FRONTEND_URL", "")]
|
|
15
|
+
allowed_origins = [origin.strip() for origin in allowed_origins if origin and origin.strip()]
|
|
16
|
+
|
|
17
|
+
app.add_middleware(
|
|
18
|
+
CORSMiddleware,
|
|
19
|
+
allow_origins=allowed_origins,
|
|
20
|
+
allow_credentials=True,
|
|
21
|
+
allow_methods=["*"],
|
|
22
|
+
allow_headers=["*"],
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
<% if (modules.auth) { -%>
|
|
26
|
+
# Auth middleware for /api routes
|
|
27
|
+
# app.middleware("http")(AuthMiddleware())
|
|
28
|
+
|
|
29
|
+
<% } -%>
|
|
30
|
+
@app.get("/health")
|
|
31
|
+
@app.get("/actuator/health")
|
|
32
|
+
async def health():
|
|
33
|
+
return {"status": "UP"}
|
|
34
|
+
|
|
35
|
+
@app.get("/api/example")
|
|
36
|
+
async def example():
|
|
37
|
+
from datetime import datetime
|
|
38
|
+
return {
|
|
39
|
+
"message": "Hello from <%= backend %> backend!",
|
|
40
|
+
"timestamp": datetime.utcnow().isoformat()
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
<% if (modules.contact) { -%>
|
|
44
|
+
# Import contact router when created
|
|
45
|
+
# from app.routers import contact
|
|
46
|
+
# app.include_router(contact.router, prefix="/api")
|
|
47
|
+
|
|
48
|
+
<% } -%>
|
|
49
|
+
<% if (modules.admin) { -%>
|
|
50
|
+
# Import admin router when created
|
|
51
|
+
# from app.routers import admin
|
|
52
|
+
# app.include_router(admin.router, prefix="/api")
|
|
53
|
+
|
|
54
|
+
<% } -%>
|
|
55
|
+
<% if (modules.payments) { -%>
|
|
56
|
+
# Import payments router when created
|
|
57
|
+
# from app.routers import payments
|
|
58
|
+
# app.include_router(payments.router, prefix="/api")
|
|
59
|
+
|
|
60
|
+
<% } -%>
|
|
61
|
+
if __name__ == "__main__":
|
|
62
|
+
import uvicorn
|
|
63
|
+
port = int(os.getenv("APP_PORT", 8080))
|
|
64
|
+
print(f"✅ Server running on http://localhost:{port}")
|
|
65
|
+
print(f"📍 API available at http://localhost:{port}/api")
|
|
66
|
+
print(f"🏥 Health check at http://localhost:{port}/health")
|
|
67
|
+
print(f"📚 API docs at http://localhost:{port}/docs")
|
|
68
|
+
uvicorn.run("app.main:app", host="0.0.0.0", port=port, reload=True)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
fastapi>=0.115.0
|
|
2
|
+
uvicorn[standard]>=0.32.0
|
|
3
|
+
python-dotenv>=1.0.0
|
|
4
|
+
pydantic>=2.10.0
|
|
5
|
+
<% if (modules.auth) { -%>
|
|
6
|
+
python-jose[cryptography]>=3.3.0
|
|
7
|
+
requests>=2.32.0
|
|
8
|
+
<% } -%>
|
|
9
|
+
<% if (modules.payments) { -%>
|
|
10
|
+
stripe>=11.0.0
|
|
11
|
+
<% } -%>
|
|
12
|
+
<% if (db === 'postgres' || db === 'mysql') { -%>
|
|
13
|
+
sqlalchemy>=2.0.0
|
|
14
|
+
alembic>=1.13.0
|
|
15
|
+
<% if (db === 'postgres') { -%>
|
|
16
|
+
psycopg2-binary>=2.9.0
|
|
17
|
+
<% } else { -%>
|
|
18
|
+
pymysql>=1.1.0
|
|
19
|
+
<% } -%>
|
|
20
|
+
<% } else { -%>
|
|
21
|
+
motor>=3.6.0
|
|
22
|
+
<% } -%>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Database
|
|
2
|
+
DB_HOST=localhost
|
|
3
|
+
<% if (db === 'postgres') { -%>
|
|
4
|
+
DB_PORT=5432
|
|
5
|
+
<% } else if (db === 'mysql') { -%>
|
|
6
|
+
DB_PORT=3306
|
|
7
|
+
<% } else { -%>
|
|
8
|
+
DB_PORT=27017
|
|
9
|
+
<% } -%>
|
|
10
|
+
DB_NAME=<%= appSlug %>_dev
|
|
11
|
+
DB_USER=<%= appSlug %>
|
|
12
|
+
DB_PASSWORD=password
|
|
13
|
+
|
|
14
|
+
# Frontend -> Backend base URL
|
|
15
|
+
PUBLIC_API_BASE=http://localhost:8080
|
|
16
|
+
<% if (modules.auth) { -%>
|
|
17
|
+
|
|
18
|
+
# Auth0
|
|
19
|
+
PUBLIC_AUTH0_DOMAIN=your-tenant.us.auth0.com
|
|
20
|
+
PUBLIC_AUTH0_CLIENT_ID=your_spa_client_id
|
|
21
|
+
PUBLIC_AUTH0_AUDIENCE=https://api.<%= appSlug %>
|
|
22
|
+
AUTH0_DOMAIN=your-tenant.us.auth0.com
|
|
23
|
+
AUTH0_AUDIENCE=https://api.<%= appSlug %>
|
|
24
|
+
<% } -%>
|
|
25
|
+
<% if (modules.payments) { -%>
|
|
26
|
+
|
|
27
|
+
# Stripe
|
|
28
|
+
STRIPE_SECRET_KEY=sk_test_xxx
|
|
29
|
+
STRIPE_WEBHOOK_SECRET=whsec_xxx
|
|
30
|
+
PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_xxx
|
|
31
|
+
<% } -%>
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main, develop ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main, develop ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
frontend:
|
|
11
|
+
name: Frontend Tests
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Setup Node.js
|
|
18
|
+
uses: actions/setup-node@v4
|
|
19
|
+
with:
|
|
20
|
+
node-version: '20'
|
|
21
|
+
cache: 'npm'
|
|
22
|
+
cache-dependency-path: frontend/package-lock.json
|
|
23
|
+
|
|
24
|
+
- name: Install dependencies
|
|
25
|
+
working-directory: frontend
|
|
26
|
+
run: npm ci
|
|
27
|
+
|
|
28
|
+
- name: Lint
|
|
29
|
+
working-directory: frontend
|
|
30
|
+
run: npm run lint
|
|
31
|
+
|
|
32
|
+
- name: Format check
|
|
33
|
+
working-directory: frontend
|
|
34
|
+
run: npm run format:check
|
|
35
|
+
|
|
36
|
+
- name: Build
|
|
37
|
+
working-directory: frontend
|
|
38
|
+
run: npm run build
|
|
39
|
+
|
|
40
|
+
backend:
|
|
41
|
+
name: Backend Tests
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
|
|
44
|
+
steps:
|
|
45
|
+
- uses: actions/checkout@v4
|
|
46
|
+
|
|
47
|
+
- name: Setup Node.js
|
|
48
|
+
uses: actions/setup-node@v4
|
|
49
|
+
with:
|
|
50
|
+
node-version: '20'
|
|
51
|
+
cache: 'npm'
|
|
52
|
+
cache-dependency-path: backend/package-lock.json
|
|
53
|
+
|
|
54
|
+
<% if (backend === 'node-express') { -%>
|
|
55
|
+
- name: Install dependencies
|
|
56
|
+
working-directory: backend
|
|
57
|
+
run: npm ci
|
|
58
|
+
|
|
59
|
+
- name: Lint
|
|
60
|
+
working-directory: backend
|
|
61
|
+
run: npm run lint
|
|
62
|
+
|
|
63
|
+
- name: Format check
|
|
64
|
+
working-directory: backend
|
|
65
|
+
run: npm run format:check
|
|
66
|
+
|
|
67
|
+
- name: Type check
|
|
68
|
+
working-directory: backend
|
|
69
|
+
run: npm run type-check
|
|
70
|
+
|
|
71
|
+
- name: Build
|
|
72
|
+
working-directory: backend
|
|
73
|
+
run: npm run build
|
|
74
|
+
<% } else if (backend === 'python-fastapi') { -%>
|
|
75
|
+
- name: Setup Python
|
|
76
|
+
uses: actions/setup-python@v5
|
|
77
|
+
with:
|
|
78
|
+
python-version: '3.11'
|
|
79
|
+
cache: 'pip'
|
|
80
|
+
|
|
81
|
+
- name: Install dependencies
|
|
82
|
+
working-directory: backend
|
|
83
|
+
run: |
|
|
84
|
+
python -m pip install --upgrade pip
|
|
85
|
+
pip install -r requirements.txt
|
|
86
|
+
|
|
87
|
+
- name: Lint
|
|
88
|
+
working-directory: backend
|
|
89
|
+
run: |
|
|
90
|
+
pip install flake8 black
|
|
91
|
+
flake8 app --max-line-length=100
|
|
92
|
+
black --check app
|
|
93
|
+
<% } else if (backend === 'java-spring') { -%>
|
|
94
|
+
- name: Setup Java
|
|
95
|
+
uses: actions/setup-java@v4
|
|
96
|
+
with:
|
|
97
|
+
distribution: 'temurin'
|
|
98
|
+
java-version: '21'
|
|
99
|
+
cache: 'maven'
|
|
100
|
+
|
|
101
|
+
- name: Build with Maven
|
|
102
|
+
working-directory: backend
|
|
103
|
+
run: mvn clean verify
|
|
104
|
+
<% } else if (backend === 'go-echo') { -%>
|
|
105
|
+
- name: Setup Go
|
|
106
|
+
uses: actions/setup-go@v5
|
|
107
|
+
with:
|
|
108
|
+
go-version: '1.22'
|
|
109
|
+
cache-dependency-path: backend/go.sum
|
|
110
|
+
|
|
111
|
+
- name: Build
|
|
112
|
+
working-directory: backend
|
|
113
|
+
run: go build -v ./...
|
|
114
|
+
|
|
115
|
+
- name: Test
|
|
116
|
+
working-directory: backend
|
|
117
|
+
run: go test -v ./...
|
|
118
|
+
|
|
119
|
+
- name: Lint
|
|
120
|
+
working-directory: backend
|
|
121
|
+
run: |
|
|
122
|
+
go install golang.org/x/lint/golint@latest
|
|
123
|
+
golint ./...
|
|
124
|
+
<% } -%>
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Example: Separate Deployment Strategy
|
|
2
|
+
#
|
|
3
|
+
# To use this strategy:
|
|
4
|
+
# 1. Split your project into two repos (see DEPLOYMENT_STRATEGIES.md)
|
|
5
|
+
# 2. Copy relevant sections to each repo's .github/workflows/deploy.yml
|
|
6
|
+
# 3. Set up deployment secrets in GitHub repo settings
|
|
7
|
+
|
|
8
|
+
# ==================================================
|
|
9
|
+
# FRONTEND DEPLOYMENT (for frontend repo)
|
|
10
|
+
# ==================================================
|
|
11
|
+
name: Deploy Frontend
|
|
12
|
+
|
|
13
|
+
on:
|
|
14
|
+
push:
|
|
15
|
+
branches: [main]
|
|
16
|
+
pull_request:
|
|
17
|
+
branches: [main]
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
test:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
|
|
25
|
+
- name: Setup Node.js
|
|
26
|
+
uses: actions/setup-node@v4
|
|
27
|
+
with:
|
|
28
|
+
node-version: '20'
|
|
29
|
+
cache: 'npm'
|
|
30
|
+
|
|
31
|
+
- name: Install dependencies
|
|
32
|
+
run: npm ci
|
|
33
|
+
|
|
34
|
+
- name: Lint
|
|
35
|
+
run: npm run lint
|
|
36
|
+
|
|
37
|
+
- name: Test
|
|
38
|
+
run: npm test
|
|
39
|
+
|
|
40
|
+
- name: Build
|
|
41
|
+
run: npm run build
|
|
42
|
+
|
|
43
|
+
deploy:
|
|
44
|
+
needs: test
|
|
45
|
+
runs-on: ubuntu-latest
|
|
46
|
+
if: github.ref == 'refs/heads/main'
|
|
47
|
+
steps:
|
|
48
|
+
- uses: actions/checkout@v4
|
|
49
|
+
|
|
50
|
+
- name: Setup Node.js
|
|
51
|
+
uses: actions/setup-node@v4
|
|
52
|
+
with:
|
|
53
|
+
node-version: '20'
|
|
54
|
+
cache: 'npm'
|
|
55
|
+
|
|
56
|
+
- name: Install dependencies
|
|
57
|
+
run: npm ci
|
|
58
|
+
|
|
59
|
+
# Option 1: Deploy to Vercel
|
|
60
|
+
- name: Deploy to Vercel
|
|
61
|
+
run: |
|
|
62
|
+
npm install -g vercel
|
|
63
|
+
vercel --prod --token ${{ secrets.VERCEL_TOKEN }}
|
|
64
|
+
|
|
65
|
+
# Option 2: Deploy to Netlify
|
|
66
|
+
# - name: Deploy to Netlify
|
|
67
|
+
# uses: nwtgck/actions-netlify@v2
|
|
68
|
+
# with:
|
|
69
|
+
# publish-dir: './dist'
|
|
70
|
+
# production-deploy: true
|
|
71
|
+
# env:
|
|
72
|
+
# NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
|
73
|
+
# NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
|
|
74
|
+
|
|
75
|
+
# Option 3: Deploy to Cloudflare Pages
|
|
76
|
+
# - name: Deploy to Cloudflare Pages
|
|
77
|
+
# uses: cloudflare/pages-action@v1
|
|
78
|
+
# with:
|
|
79
|
+
# apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
|
80
|
+
# accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
|
81
|
+
# projectName: my-app
|
|
82
|
+
# directory: dist
|
|
83
|
+
|
|
84
|
+
# ==================================================
|
|
85
|
+
# BACKEND DEPLOYMENT (for backend repo)
|
|
86
|
+
# ==================================================
|
|
87
|
+
name: Deploy Backend
|
|
88
|
+
|
|
89
|
+
on:
|
|
90
|
+
push:
|
|
91
|
+
branches: [main]
|
|
92
|
+
pull_request:
|
|
93
|
+
branches: [main]
|
|
94
|
+
|
|
95
|
+
jobs:
|
|
96
|
+
test:
|
|
97
|
+
runs-on: ubuntu-latest
|
|
98
|
+
steps:
|
|
99
|
+
- uses: actions/checkout@v4
|
|
100
|
+
|
|
101
|
+
- name: Setup Node.js
|
|
102
|
+
uses: actions/setup-node@v4
|
|
103
|
+
with:
|
|
104
|
+
node-version: '20'
|
|
105
|
+
cache: 'npm'
|
|
106
|
+
|
|
107
|
+
- name: Install dependencies
|
|
108
|
+
run: npm ci
|
|
109
|
+
|
|
110
|
+
- name: Lint
|
|
111
|
+
run: npm run lint
|
|
112
|
+
|
|
113
|
+
- name: Type check
|
|
114
|
+
run: npm run type-check
|
|
115
|
+
|
|
116
|
+
- name: Build
|
|
117
|
+
run: npm run build
|
|
118
|
+
|
|
119
|
+
deploy:
|
|
120
|
+
needs: test
|
|
121
|
+
runs-on: ubuntu-latest
|
|
122
|
+
if: github.ref == 'refs/heads/main'
|
|
123
|
+
steps:
|
|
124
|
+
- uses: actions/checkout@v4
|
|
125
|
+
|
|
126
|
+
# Option 1: Deploy to Fly.io
|
|
127
|
+
- name: Deploy to Fly.io
|
|
128
|
+
uses: superfly/flyctl-actions/setup-flyctl@master
|
|
129
|
+
- run: flyctl deploy --remote-only
|
|
130
|
+
env:
|
|
131
|
+
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
|
|
132
|
+
|
|
133
|
+
# Option 2: Deploy to Railway
|
|
134
|
+
# - name: Deploy to Railway
|
|
135
|
+
# run: |
|
|
136
|
+
# npm install -g @railway/cli
|
|
137
|
+
# railway up
|
|
138
|
+
# env:
|
|
139
|
+
# RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
|
|
140
|
+
|
|
141
|
+
# Option 3: Deploy to Render
|
|
142
|
+
# - name: Deploy to Render
|
|
143
|
+
# run: |
|
|
144
|
+
# curl -X POST ${{ secrets.RENDER_DEPLOY_HOOK }}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"recommendations": [
|
|
3
|
+
"dbaeumer.vscode-eslint",
|
|
4
|
+
"esbenp.prettier-vscode",
|
|
5
|
+
"ms-vscode.vscode-typescript-next"<% if (frontend === 'vue') { %>,
|
|
6
|
+
"Vue.volar"<% } %><% if (frontend === 'svelte') { %>,
|
|
7
|
+
"svelte.svelte-vscode"<% } %><% if (frontend === 'angular') { %>,
|
|
8
|
+
"Angular.ng-template"<% } %><% if (backend === 'python-fastapi') { %>,
|
|
9
|
+
"ms-python.python",
|
|
10
|
+
"ms-python.vscode-pylance",
|
|
11
|
+
"ms-python.black-formatter"<% } %><% if (backend === 'java-spring') { %>,
|
|
12
|
+
"vscjava.vscode-java-pack",
|
|
13
|
+
"vscjava.vscode-spring-boot-dashboard"<% } %><% if (backend === 'go-echo') { %>,
|
|
14
|
+
"golang.go"<% } %>,
|
|
15
|
+
"ms-azuretools.vscode-docker"
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"editor.formatOnSave": true,
|
|
3
|
+
"editor.codeActionsOnSave": {
|
|
4
|
+
"source.fixAll": "explicit"
|
|
5
|
+
},
|
|
6
|
+
"files.exclude": {
|
|
7
|
+
"**/.git": true,
|
|
8
|
+
"**/.DS_Store": true,
|
|
9
|
+
"**/node_modules": true
|
|
10
|
+
},
|
|
11
|
+
"search.exclude": {
|
|
12
|
+
"**/node_modules": true,
|
|
13
|
+
"**/dist": true,
|
|
14
|
+
"**/build": true,
|
|
15
|
+
"**/.next": true
|
|
16
|
+
},
|
|
17
|
+
"[javascript]": {
|
|
18
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
19
|
+
"editor.tabSize": 2
|
|
20
|
+
},
|
|
21
|
+
"[typescript]": {
|
|
22
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
23
|
+
"editor.tabSize": 2
|
|
24
|
+
},
|
|
25
|
+
"[json]": {
|
|
26
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
27
|
+
"editor.tabSize": 2
|
|
28
|
+
}<% if (backend === 'python-fastapi') { %>,
|
|
29
|
+
"[python]": {
|
|
30
|
+
"editor.defaultFormatter": "ms-python.black-formatter",
|
|
31
|
+
"editor.tabSize": 4,
|
|
32
|
+
"editor.insertSpaces": true
|
|
33
|
+
},
|
|
34
|
+
"python.linting.enabled": true,
|
|
35
|
+
"python.linting.pylintEnabled": false,
|
|
36
|
+
"python.linting.flake8Enabled": true,
|
|
37
|
+
"python.formatting.provider": "black"<% } %><% if (backend === 'java-spring') { %>,
|
|
38
|
+
"[java]": {
|
|
39
|
+
"editor.tabSize": 4
|
|
40
|
+
},
|
|
41
|
+
"java.configuration.updateBuildConfiguration": "automatic"<% } %><% if (backend === 'go-echo') { %>,
|
|
42
|
+
"[go]": {
|
|
43
|
+
"editor.defaultFormatter": "golang.go",
|
|
44
|
+
"editor.tabSize": 4,
|
|
45
|
+
"editor.insertSpaces": false
|
|
46
|
+
},
|
|
47
|
+
"go.useLanguageServer": true,
|
|
48
|
+
"go.formatTool": "gofmt"<% } %>
|
|
49
|
+
}
|