Files
claude-skills-reference/engineering-team/fullstack-engineer/scripts/project_scaffolder.py
Reza Rezvani 0c39593cba 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>
2025-10-19 15:24:51 +02:00

850 lines
24 KiB
Python

#!/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()