feat: add engineering team skills with fullstack-engineer package
Add comprehensive fullstack engineering skill package: Fullstack Engineer: - Code quality analyzer (Python tool) - Fullstack scaffolder for rapid project setup (Python tool) - Project scaffolder with best practices (Python tool) - Architecture patterns reference (MVC, microservices, event-driven) - Development workflows (Git, CI/CD, testing) - Tech stack guide (frontend, backend, database, DevOps) Includes packaged .zip archive for easy distribution and comprehensive roadmap for future engineering skills. This expands the library to 9 production-ready skills across 4 domains: Marketing, C-Level, Product Team, and Engineering. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,849 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Project Scaffolder - Quickly scaffold fullstack projects with best practices
|
||||
"""
|
||||
|
||||
import os
|
||||
import json
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from typing import Dict, List
|
||||
import argparse
|
||||
|
||||
class ProjectScaffolder:
|
||||
def __init__(self, project_name: str, project_type: str):
|
||||
self.project_name = project_name
|
||||
self.project_type = project_type
|
||||
self.root_path = Path.cwd() / project_name
|
||||
|
||||
def create_nextjs_graphql_project(self):
|
||||
"""Create a Next.js + GraphQL + PostgreSQL project"""
|
||||
print(f"🚀 Creating Next.js + GraphQL project: {self.project_name}")
|
||||
|
||||
# Create project structure
|
||||
dirs = [
|
||||
"frontend/src/components",
|
||||
"frontend/src/pages/api",
|
||||
"frontend/src/lib",
|
||||
"frontend/src/hooks",
|
||||
"frontend/src/styles",
|
||||
"frontend/src/types",
|
||||
"frontend/src/utils",
|
||||
"frontend/public",
|
||||
"backend/src/resolvers",
|
||||
"backend/src/schema",
|
||||
"backend/src/models",
|
||||
"backend/src/services",
|
||||
"backend/src/middleware",
|
||||
"backend/src/utils",
|
||||
"backend/src/types",
|
||||
"database/migrations",
|
||||
"database/seeds",
|
||||
"docker",
|
||||
"tests/unit",
|
||||
"tests/integration",
|
||||
"tests/e2e",
|
||||
".github/workflows"
|
||||
]
|
||||
|
||||
for dir_path in dirs:
|
||||
(self.root_path / dir_path).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Create configuration files
|
||||
self._create_package_json()
|
||||
self._create_docker_compose()
|
||||
self._create_env_example()
|
||||
self._create_typescript_config()
|
||||
self._create_eslint_config()
|
||||
self._create_prettier_config()
|
||||
self._create_github_workflows()
|
||||
self._create_readme()
|
||||
|
||||
print("✅ Project structure created successfully!")
|
||||
|
||||
def _create_package_json(self):
|
||||
"""Create package.json files for frontend and backend"""
|
||||
|
||||
# Frontend package.json
|
||||
frontend_package = {
|
||||
"name": f"{self.project_name}-frontend",
|
||||
"version": "1.0.0",
|
||||
"private": True,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint",
|
||||
"test": "jest --watch",
|
||||
"test:ci": "jest --ci --coverage",
|
||||
"type-check": "tsc --noEmit",
|
||||
"format": "prettier --write ."
|
||||
},
|
||||
"dependencies": {
|
||||
"next": "^14.0.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"@apollo/client": "^3.8.0",
|
||||
"graphql": "^16.8.0",
|
||||
"axios": "^1.6.0",
|
||||
"@tanstack/react-query": "^5.0.0",
|
||||
"zustand": "^4.4.0",
|
||||
"zod": "^3.22.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.0.0",
|
||||
"@types/react": "^18.2.0",
|
||||
"@types/react-dom": "^18.2.0",
|
||||
"typescript": "^5.3.0",
|
||||
"eslint": "^8.50.0",
|
||||
"eslint-config-next": "^14.0.0",
|
||||
"prettier": "^3.1.0",
|
||||
"jest": "^29.7.0",
|
||||
"@testing-library/react": "^14.1.0",
|
||||
"@testing-library/jest-dom": "^6.1.0",
|
||||
"cypress": "^13.6.0"
|
||||
}
|
||||
}
|
||||
|
||||
# Backend package.json
|
||||
backend_package = {
|
||||
"name": f"{self.project_name}-backend",
|
||||
"version": "1.0.0",
|
||||
"private": True,
|
||||
"scripts": {
|
||||
"dev": "nodemon --exec ts-node src/index.ts",
|
||||
"build": "tsc",
|
||||
"start": "node dist/index.js",
|
||||
"test": "jest --watch",
|
||||
"test:ci": "jest --ci --coverage",
|
||||
"lint": "eslint src --ext .ts",
|
||||
"format": "prettier --write src",
|
||||
"migrate": "knex migrate:latest",
|
||||
"seed": "knex seed:run"
|
||||
},
|
||||
"dependencies": {
|
||||
"apollo-server-express": "^3.13.0",
|
||||
"express": "^4.18.0",
|
||||
"graphql": "^16.8.0",
|
||||
"pg": "^8.11.0",
|
||||
"knex": "^3.1.0",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"dotenv": "^16.3.0",
|
||||
"cors": "^2.8.5",
|
||||
"helmet": "^7.1.0",
|
||||
"winston": "^3.11.0",
|
||||
"joi": "^17.11.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.0.0",
|
||||
"@types/express": "^4.17.0",
|
||||
"@types/bcryptjs": "^2.4.0",
|
||||
"@types/jsonwebtoken": "^9.0.0",
|
||||
"typescript": "^5.3.0",
|
||||
"ts-node": "^10.9.0",
|
||||
"nodemon": "^3.0.0",
|
||||
"eslint": "^8.50.0",
|
||||
"@typescript-eslint/parser": "^6.10.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.10.0",
|
||||
"prettier": "^3.1.0",
|
||||
"jest": "^29.7.0",
|
||||
"@types/jest": "^29.5.0",
|
||||
"supertest": "^6.3.0"
|
||||
}
|
||||
}
|
||||
|
||||
# Write package.json files
|
||||
with open(self.root_path / "frontend" / "package.json", "w") as f:
|
||||
json.dump(frontend_package, f, indent=2)
|
||||
|
||||
with open(self.root_path / "backend" / "package.json", "w") as f:
|
||||
json.dump(backend_package, f, indent=2)
|
||||
|
||||
def _create_docker_compose(self):
|
||||
"""Create docker-compose.yml for local development"""
|
||||
docker_compose = """version: '3.8'
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:15-alpine
|
||||
environment:
|
||||
POSTGRES_USER: ${DB_USER:-developer}
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD:-password}
|
||||
POSTGRES_DB: ${DB_NAME:-projectdb}
|
||||
ports:
|
||||
- "5432:5432"
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
- ./database/init.sql:/docker-entrypoint-initdb.d/init.sql
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-developer}"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
backend:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: ../docker/backend.Dockerfile
|
||||
ports:
|
||||
- "4000:4000"
|
||||
environment:
|
||||
NODE_ENV: development
|
||||
DATABASE_URL: postgresql://${DB_USER:-developer}:${DB_PASSWORD:-password}@postgres:5432/${DB_NAME:-projectdb}
|
||||
REDIS_URL: redis://redis:6379
|
||||
JWT_SECRET: ${JWT_SECRET:-your-secret-key}
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
volumes:
|
||||
- ./backend:/app
|
||||
- /app/node_modules
|
||||
command: npm run dev
|
||||
|
||||
frontend:
|
||||
build:
|
||||
context: ./frontend
|
||||
dockerfile: ../docker/frontend.Dockerfile
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
NEXT_PUBLIC_API_URL: http://backend:4000/graphql
|
||||
depends_on:
|
||||
- backend
|
||||
volumes:
|
||||
- ./frontend:/app
|
||||
- /app/node_modules
|
||||
- /app/.next
|
||||
command: npm run dev
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
redis_data:
|
||||
"""
|
||||
with open(self.root_path / "docker-compose.yml", "w") as f:
|
||||
f.write(docker_compose)
|
||||
|
||||
# Create Dockerfiles
|
||||
backend_dockerfile = """FROM node:18-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN npm run build
|
||||
|
||||
EXPOSE 4000
|
||||
|
||||
CMD ["npm", "start"]
|
||||
"""
|
||||
|
||||
frontend_dockerfile = """FROM node:18-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN npm run build
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["npm", "start"]
|
||||
"""
|
||||
|
||||
with open(self.root_path / "docker" / "backend.Dockerfile", "w") as f:
|
||||
f.write(backend_dockerfile)
|
||||
|
||||
with open(self.root_path / "docker" / "frontend.Dockerfile", "w") as f:
|
||||
f.write(frontend_dockerfile)
|
||||
|
||||
def _create_env_example(self):
|
||||
"""Create .env.example file"""
|
||||
env_content = """# Database
|
||||
DB_HOST=localhost
|
||||
DB_PORT=5432
|
||||
DB_USER=developer
|
||||
DB_PASSWORD=password
|
||||
DB_NAME=projectdb
|
||||
DATABASE_URL=postgresql://developer:password@localhost:5432/projectdb
|
||||
|
||||
# Redis
|
||||
REDIS_URL=redis://localhost:6379
|
||||
|
||||
# JWT
|
||||
JWT_SECRET=your-secret-key-change-this-in-production
|
||||
JWT_EXPIRY=7d
|
||||
|
||||
# API
|
||||
API_PORT=4000
|
||||
NEXT_PUBLIC_API_URL=http://localhost:4000/graphql
|
||||
|
||||
# Frontend
|
||||
NEXT_PUBLIC_APP_URL=http://localhost:3000
|
||||
|
||||
# Environment
|
||||
NODE_ENV=development
|
||||
|
||||
# Monitoring (optional)
|
||||
SENTRY_DSN=
|
||||
NEW_RELIC_LICENSE_KEY=
|
||||
|
||||
# AWS (optional)
|
||||
AWS_REGION=
|
||||
AWS_ACCESS_KEY_ID=
|
||||
AWS_SECRET_ACCESS_KEY=
|
||||
S3_BUCKET_NAME=
|
||||
"""
|
||||
with open(self.root_path / ".env.example", "w") as f:
|
||||
f.write(env_content)
|
||||
|
||||
def _create_typescript_config(self):
|
||||
"""Create TypeScript configuration files"""
|
||||
|
||||
# Frontend tsconfig.json
|
||||
frontend_tsconfig = {
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": True,
|
||||
"skipLibCheck": True,
|
||||
"strict": True,
|
||||
"forceConsistentCasingInFileNames": True,
|
||||
"noEmit": True,
|
||||
"esModuleInterop": True,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": True,
|
||||
"isolatedModules": True,
|
||||
"jsx": "preserve",
|
||||
"incremental": True,
|
||||
"paths": {
|
||||
"@/*": ["./src/*"],
|
||||
"@components/*": ["./src/components/*"],
|
||||
"@hooks/*": ["./src/hooks/*"],
|
||||
"@lib/*": ["./src/lib/*"],
|
||||
"@types/*": ["./src/types/*"],
|
||||
"@utils/*": ["./src/utils/*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
||||
# Backend tsconfig.json
|
||||
backend_tsconfig = {
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "commonjs",
|
||||
"lib": ["ES2022"],
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"strict": True,
|
||||
"esModuleInterop": True,
|
||||
"skipLibCheck": True,
|
||||
"forceConsistentCasingInFileNames": True,
|
||||
"resolveJsonModule": True,
|
||||
"declaration": True,
|
||||
"declarationMap": True,
|
||||
"sourceMap": True,
|
||||
"noUnusedLocals": True,
|
||||
"noUnusedParameters": True,
|
||||
"noImplicitReturns": True,
|
||||
"noFallthroughCasesInSwitch": True,
|
||||
"paths": {
|
||||
"@/*": ["./src/*"],
|
||||
"@models/*": ["./src/models/*"],
|
||||
"@services/*": ["./src/services/*"],
|
||||
"@resolvers/*": ["./src/resolvers/*"],
|
||||
"@middleware/*": ["./src/middleware/*"],
|
||||
"@utils/*": ["./src/utils/*"],
|
||||
"@types/*": ["./src/types/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist", "**/*.test.ts"]
|
||||
}
|
||||
|
||||
with open(self.root_path / "frontend" / "tsconfig.json", "w") as f:
|
||||
json.dump(frontend_tsconfig, f, indent=2)
|
||||
|
||||
with open(self.root_path / "backend" / "tsconfig.json", "w") as f:
|
||||
json.dump(backend_tsconfig, f, indent=2)
|
||||
|
||||
def _create_eslint_config(self):
|
||||
"""Create ESLint configuration"""
|
||||
eslintrc = {
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:react/recommended",
|
||||
"plugin:react-hooks/recommended",
|
||||
"next/core-web-vitals",
|
||||
"prettier"
|
||||
],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": ["@typescript-eslint", "react", "react-hooks"],
|
||||
"rules": {
|
||||
"@typescript-eslint/no-unused-vars": ["error", {"argsIgnorePattern": "^_"}],
|
||||
"@typescript-eslint/no-explicit-any": "error",
|
||||
"react/react-in-jsx-scope": "off",
|
||||
"react/prop-types": "off",
|
||||
"no-console": ["warn", {"allow": ["warn", "error"]}]
|
||||
}
|
||||
}
|
||||
|
||||
with open(self.root_path / ".eslintrc.json", "w") as f:
|
||||
json.dump(eslintrc, f, indent=2)
|
||||
|
||||
def _create_prettier_config(self):
|
||||
"""Create Prettier configuration"""
|
||||
prettierrc = {
|
||||
"semi": True,
|
||||
"singleQuote": True,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "es5",
|
||||
"printWidth": 100,
|
||||
"bracketSpacing": True,
|
||||
"arrowParens": "always",
|
||||
"endOfLine": "lf"
|
||||
}
|
||||
|
||||
with open(self.root_path / ".prettierrc", "w") as f:
|
||||
json.dump(prettierrc, f, indent=2)
|
||||
|
||||
# .prettierignore
|
||||
prettierignore = """node_modules
|
||||
dist
|
||||
.next
|
||||
coverage
|
||||
*.log
|
||||
.env
|
||||
.env.local
|
||||
"""
|
||||
with open(self.root_path / ".prettierignore", "w") as f:
|
||||
f.write(prettierignore)
|
||||
|
||||
def _create_github_workflows(self):
|
||||
"""Create GitHub Actions workflows"""
|
||||
ci_workflow = """name: CI/CD Pipeline
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, develop]
|
||||
pull_request:
|
||||
branches: [main, develop]
|
||||
|
||||
env:
|
||||
NODE_VERSION: '18'
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd frontend && npm ci
|
||||
cd ../backend && npm ci
|
||||
|
||||
- name: Run ESLint
|
||||
run: |
|
||||
cd frontend && npm run lint
|
||||
cd ../backend && npm run lint
|
||||
|
||||
- name: Run Type Check
|
||||
run: |
|
||||
cd frontend && npm run type-check
|
||||
cd ../backend && npx tsc --noEmit
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:15
|
||||
env:
|
||||
POSTGRES_USER: test
|
||||
POSTGRES_PASSWORD: test
|
||||
POSTGRES_DB: testdb
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
redis:
|
||||
image: redis:7
|
||||
options: >-
|
||||
--health-cmd "redis-cli ping"
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 6379:6379
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd frontend && npm ci
|
||||
cd ../backend && npm ci
|
||||
|
||||
- name: Run backend tests
|
||||
env:
|
||||
DATABASE_URL: postgresql://test:test@localhost:5432/testdb
|
||||
REDIS_URL: redis://localhost:6379
|
||||
JWT_SECRET: test-secret
|
||||
run: |
|
||||
cd backend
|
||||
npm run test:ci
|
||||
|
||||
- name: Run frontend tests
|
||||
run: |
|
||||
cd frontend
|
||||
npm run test:ci
|
||||
|
||||
- name: Upload coverage
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
files: ./frontend/coverage/lcov.info,./backend/coverage/lcov.info
|
||||
|
||||
security:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Run security audit
|
||||
run: |
|
||||
cd frontend && npm audit --audit-level=moderate
|
||||
cd ../backend && npm audit --audit-level=moderate
|
||||
|
||||
- name: Run Snyk security scan
|
||||
uses: snyk/actions/node@master
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
with:
|
||||
args: --severity-threshold=high
|
||||
|
||||
build:
|
||||
needs: [lint, test]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
cache: 'npm'
|
||||
|
||||
- name: Build frontend
|
||||
run: |
|
||||
cd frontend
|
||||
npm ci
|
||||
npm run build
|
||||
|
||||
- name: Build backend
|
||||
run: |
|
||||
cd backend
|
||||
npm ci
|
||||
npm run build
|
||||
|
||||
- name: Build Docker images
|
||||
run: |
|
||||
docker build -f docker/frontend.Dockerfile -t frontend:latest ./frontend
|
||||
docker build -f docker/backend.Dockerfile -t backend:latest ./backend
|
||||
"""
|
||||
with open(self.root_path / ".github" / "workflows" / "ci.yml", "w") as f:
|
||||
f.write(ci_workflow)
|
||||
|
||||
def _create_readme(self):
|
||||
"""Create comprehensive README.md"""
|
||||
readme = f"""# {self.project_name}
|
||||
|
||||
## 🚀 Tech Stack
|
||||
|
||||
### Frontend
|
||||
- **Framework**: Next.js 14 with TypeScript
|
||||
- **State Management**: Zustand
|
||||
- **Data Fetching**: Apollo Client (GraphQL) & TanStack Query
|
||||
- **Styling**: Tailwind CSS / CSS Modules
|
||||
- **Testing**: Jest, React Testing Library, Cypress
|
||||
|
||||
### Backend
|
||||
- **Runtime**: Node.js with TypeScript
|
||||
- **Framework**: Express + Apollo Server
|
||||
- **Database**: PostgreSQL with Knex.js
|
||||
- **Caching**: Redis
|
||||
- **Authentication**: JWT
|
||||
- **Testing**: Jest, Supertest
|
||||
|
||||
### DevOps
|
||||
- **Containerization**: Docker & Docker Compose
|
||||
- **CI/CD**: GitHub Actions
|
||||
- **Monitoring**: Sentry, New Relic (optional)
|
||||
- **Cloud**: AWS/GCP/Azure ready
|
||||
|
||||
## 📦 Project Structure
|
||||
|
||||
```
|
||||
{self.project_name}/
|
||||
├── frontend/ # Next.js application
|
||||
│ ├── src/
|
||||
│ │ ├── components/ # React components
|
||||
│ │ ├── pages/ # Next.js pages
|
||||
│ │ ├── hooks/ # Custom React hooks
|
||||
│ │ ├── lib/ # Libraries and configs
|
||||
│ │ ├── styles/ # Global styles
|
||||
│ │ ├── types/ # TypeScript types
|
||||
│ │ └── utils/ # Utility functions
|
||||
│ └── public/ # Static assets
|
||||
├── backend/ # Node.js GraphQL API
|
||||
│ └── src/
|
||||
│ ├── resolvers/ # GraphQL resolvers
|
||||
│ ├── schema/ # GraphQL schema
|
||||
│ ├── models/ # Database models
|
||||
│ ├── services/ # Business logic
|
||||
│ ├── middleware/ # Express middleware
|
||||
│ └── utils/ # Utilities
|
||||
├── database/ # Database files
|
||||
│ ├── migrations/ # Database migrations
|
||||
│ └── seeds/ # Seed data
|
||||
├── tests/ # Test files
|
||||
│ ├── unit/ # Unit tests
|
||||
│ ├── integration/ # Integration tests
|
||||
│ └── e2e/ # End-to-end tests
|
||||
├── docker/ # Docker configurations
|
||||
└── .github/ # GitHub Actions workflows
|
||||
```
|
||||
|
||||
## 🛠️ Getting Started
|
||||
|
||||
### Prerequisites
|
||||
- Node.js 18+
|
||||
- Docker & Docker Compose
|
||||
- PostgreSQL 15+ (or use Docker)
|
||||
- Redis 7+ (or use Docker)
|
||||
|
||||
### Installation
|
||||
|
||||
1. Clone the repository
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd {self.project_name}
|
||||
```
|
||||
|
||||
2. Copy environment variables
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# Edit .env with your values
|
||||
```
|
||||
|
||||
3. Start services with Docker Compose
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
4. Install dependencies
|
||||
```bash
|
||||
# Frontend
|
||||
cd frontend && npm install
|
||||
|
||||
# Backend
|
||||
cd ../backend && npm install
|
||||
```
|
||||
|
||||
5. Run database migrations
|
||||
```bash
|
||||
cd backend
|
||||
npm run migrate
|
||||
npm run seed # Optional: seed data
|
||||
```
|
||||
|
||||
6. Start development servers
|
||||
```bash
|
||||
# Terminal 1 - Backend
|
||||
cd backend && npm run dev
|
||||
|
||||
# Terminal 2 - Frontend
|
||||
cd frontend && npm run dev
|
||||
```
|
||||
|
||||
Visit:
|
||||
- Frontend: http://localhost:3000
|
||||
- GraphQL Playground: http://localhost:4000/graphql
|
||||
- PostgreSQL: localhost:5432
|
||||
- Redis: localhost:6379
|
||||
|
||||
## 📝 Development
|
||||
|
||||
### Commands
|
||||
|
||||
#### Frontend
|
||||
```bash
|
||||
npm run dev # Start development server
|
||||
npm run build # Build for production
|
||||
npm run start # Start production server
|
||||
npm run test # Run tests
|
||||
npm run lint # Lint code
|
||||
npm run type-check # TypeScript check
|
||||
```
|
||||
|
||||
#### Backend
|
||||
```bash
|
||||
npm run dev # Start development server
|
||||
npm run build # Build TypeScript
|
||||
npm run start # Start production server
|
||||
npm run test # Run tests
|
||||
npm run lint # Lint code
|
||||
npm run migrate # Run migrations
|
||||
npm run seed # Run seeders
|
||||
```
|
||||
|
||||
### Code Style
|
||||
- ESLint for linting
|
||||
- Prettier for formatting
|
||||
- Husky for pre-commit hooks
|
||||
- Conventional Commits
|
||||
|
||||
### Testing Strategy
|
||||
- Unit Tests: Jest
|
||||
- Integration Tests: Supertest
|
||||
- E2E Tests: Cypress
|
||||
- Coverage Goal: 80%+
|
||||
|
||||
## 🚀 Deployment
|
||||
|
||||
### Using Docker
|
||||
```bash
|
||||
# Build images
|
||||
docker build -f docker/frontend.Dockerfile -t {self.project_name}-frontend:latest ./frontend
|
||||
docker build -f docker/backend.Dockerfile -t {self.project_name}-backend:latest ./backend
|
||||
|
||||
# Run containers
|
||||
docker-compose -f docker-compose.production.yml up -d
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
See `.env.example` for all required environment variables.
|
||||
|
||||
## 📊 Monitoring
|
||||
|
||||
- **Error Tracking**: Sentry
|
||||
- **APM**: New Relic / DataDog
|
||||
- **Logs**: Winston + CloudWatch
|
||||
- **Metrics**: Prometheus + Grafana
|
||||
|
||||
## 🔒 Security
|
||||
|
||||
- JWT authentication
|
||||
- Input validation with Joi/Zod
|
||||
- SQL injection prevention (Knex.js)
|
||||
- XSS protection (React)
|
||||
- CORS configuration
|
||||
- Rate limiting
|
||||
- Security headers (Helmet)
|
||||
|
||||
## 📚 Documentation
|
||||
|
||||
- API Documentation: `/graphql` (GraphQL Playground)
|
||||
- Component Storybook: `npm run storybook`
|
||||
- Database Schema: `/database/schema.md`
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
1. Fork the repository
|
||||
2. Create feature branch (`git checkout -b feature/amazing-feature`)
|
||||
3. Commit changes (`git commit -m 'feat: add amazing feature'`)
|
||||
4. Push to branch (`git push origin feature/amazing-feature`)
|
||||
5. Open Pull Request
|
||||
|
||||
## 📄 License
|
||||
|
||||
This project is licensed under the MIT License.
|
||||
"""
|
||||
with open(self.root_path / "README.md", "w") as f:
|
||||
f.write(readme)
|
||||
|
||||
def scaffold(self):
|
||||
"""Main scaffolding method"""
|
||||
if self.project_type == "nextjs-graphql":
|
||||
self.create_nextjs_graphql_project()
|
||||
elif self.project_type == "react-native":
|
||||
self.create_react_native_project()
|
||||
elif self.project_type == "microservices":
|
||||
self.create_microservices_project()
|
||||
else:
|
||||
print(f"Project type '{self.project_type}' not supported")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def create_react_native_project(self):
|
||||
"""Create React Native project structure"""
|
||||
# Implementation for React Native
|
||||
print("React Native scaffolding - to be implemented")
|
||||
|
||||
def create_microservices_project(self):
|
||||
"""Create Microservices architecture"""
|
||||
# Implementation for Microservices
|
||||
print("Microservices scaffolding - to be implemented")
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Scaffold a fullstack project')
|
||||
parser.add_argument('project_name', help='Name of the project')
|
||||
parser.add_argument('--type',
|
||||
choices=['nextjs-graphql', 'react-native', 'microservices'],
|
||||
default='nextjs-graphql',
|
||||
help='Type of project to scaffold')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
scaffolder = ProjectScaffolder(args.project_name, args.type)
|
||||
if scaffolder.scaffold():
|
||||
print(f"\n✨ Project '{args.project_name}' created successfully!")
|
||||
print(f"📁 Location: {scaffolder.root_path}")
|
||||
print("\n🎯 Next steps:")
|
||||
print(" 1. cd " + args.project_name)
|
||||
print(" 2. docker-compose up -d")
|
||||
print(" 3. cd frontend && npm install")
|
||||
print(" 4. cd ../backend && npm install")
|
||||
print(" 5. npm run dev (in both directories)")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user