Files
claude-skills-reference/engineering-team/fullstack-engineer/references/development_workflows.md
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

1057 lines
22 KiB
Markdown

# Development Workflows & Best Practices
## Git Workflow
### 1. GitFlow Model
```
main (production)
├── hotfix/critical-bug
└── release/v1.2.0
└── develop
├── feature/user-auth
├── feature/payment-integration
└── bugfix/login-error
```
#### Branch Naming Conventions
- `feature/` - New features
- `bugfix/` - Bug fixes in development
- `hotfix/` - Critical production fixes
- `release/` - Release preparation
- `chore/` - Maintenance tasks
- `docs/` - Documentation updates
#### Commit Message Format
```
<type>(<scope>): <subject>
<body>
<footer>
```
**Types:**
- `feat`: New feature
- `fix`: Bug fix
- `docs`: Documentation
- `style`: Formatting
- `refactor`: Code restructuring
- `perf`: Performance improvement
- `test`: Testing
- `chore`: Maintenance
- `ci`: CI/CD changes
**Examples:**
```bash
git commit -m "feat(auth): add JWT authentication
- Implement login endpoint
- Add JWT token generation
- Add refresh token mechanism
Closes #123"
```
### 2. Pull Request Workflow
#### PR Template
```markdown
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix (non-breaking change)
- [ ] New feature (non-breaking change)
- [ ] Breaking change
- [ ] Documentation update
## Testing
- [ ] Unit tests pass
- [ ] Integration tests pass
- [ ] Manual testing completed
## Checklist
- [ ] Code follows style guidelines
- [ ] Self-review completed
- [ ] Comments added for complex code
- [ ] Documentation updated
- [ ] No new warnings
- [ ] Tests added/updated
- [ ] All tests passing
## Screenshots (if applicable)
[Add screenshots]
## Related Issues
Closes #issue_number
```
#### Code Review Checklist
- **Functionality**: Does it work as expected?
- **Design**: Is the code well-designed?
- **Complexity**: Could it be simpler?
- **Tests**: Are there adequate tests?
- **Naming**: Are names clear and consistent?
- **Comments**: Are comments necessary and helpful?
- **Style**: Does it follow style guides?
- **Documentation**: Is documentation updated?
- **Performance**: Any performance concerns?
- **Security**: Any security issues?
### 3. Branching Strategies
#### Feature Branch Workflow
```bash
# Create feature branch
git checkout -b feature/user-profile
# Work on feature
git add .
git commit -m "feat: add user profile page"
# Keep branch updated
git checkout develop
git pull origin develop
git checkout feature/user-profile
git rebase develop
# Push and create PR
git push origin feature/user-profile
```
#### Release Process
```bash
# Create release branch
git checkout -b release/v1.2.0 develop
# Bump version
npm version minor
# Final testing and fixes
git commit -m "fix: resolve release issues"
# Merge to main
git checkout main
git merge --no-ff release/v1.2.0
git tag -a v1.2.0 -m "Release version 1.2.0"
# Merge back to develop
git checkout develop
git merge --no-ff release/v1.2.0
# Clean up
git branch -d release/v1.2.0
git push origin main develop --tags
```
## Development Environment Setup
### 1. VS Code Configuration
#### Essential Extensions
```json
{
"recommendations": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"ms-vscode.vscode-typescript-next",
"bradlc.vscode-tailwindcss",
"prisma.prisma",
"graphql.vscode-graphql",
"eamodio.gitlens",
"github.copilot",
"ms-azuretools.vscode-docker",
"mikestead.dotenv",
"usernamehw.errorlens",
"yoavbls.pretty-ts-errors"
]
}
```
#### Settings.json
```json
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.organizeImports": true
},
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"typescript.updateImportsOnFileMove.enabled": "always",
"typescript.preferences.includePackageJsonAutoImports": "on",
"files.exclude": {
"**/.git": true,
"**/.DS_Store": true,
"**/node_modules": true,
"**/dist": true,
"**/.next": true
},
"search.exclude": {
"**/node_modules": true,
"**/dist": true,
"**/.next": true,
"**/coverage": true
}
}
```
### 2. Pre-commit Hooks
#### Husky + Lint-staged Setup
```bash
npm install -D husky lint-staged
npx husky install
npx husky add .husky/pre-commit "npx lint-staged"
```
#### .lintstagedrc.json
```json
{
"*.{ts,tsx,js,jsx}": [
"eslint --fix",
"prettier --write"
],
"*.{json,md,yml,yaml}": [
"prettier --write"
],
"*.test.{ts,tsx}": [
"jest --bail --findRelatedTests"
]
}
```
### 3. Environment Management
#### .env Structure
```bash
# .env.local (development)
NODE_ENV=development
DATABASE_URL=postgresql://dev:dev@localhost:5432/devdb
REDIS_URL=redis://localhost:6379
API_URL=http://localhost:4000
NEXT_PUBLIC_API_URL=http://localhost:4000
# .env.test (testing)
NODE_ENV=test
DATABASE_URL=postgresql://test:test@localhost:5432/testdb
REDIS_URL=redis://localhost:6380
API_URL=http://localhost:4001
# .env.production (production)
NODE_ENV=production
DATABASE_URL=${SECRET_DATABASE_URL}
REDIS_URL=${SECRET_REDIS_URL}
API_URL=https://api.example.com
```
#### Environment Validation
```typescript
// env.config.ts
import { z } from 'zod';
const envSchema = z.object({
NODE_ENV: z.enum(['development', 'test', 'production']),
DATABASE_URL: z.string().url(),
REDIS_URL: z.string().url(),
JWT_SECRET: z.string().min(32),
PORT: z.string().transform(Number).default('4000'),
});
export const env = envSchema.parse(process.env);
```
## Testing Strategy
### 1. Test Pyramid
```
/\ E2E Tests (10%)
/ \ - Critical user journeys
/ \ - Cross-browser testing
/ \
/ \ Integration Tests (30%)
/ \ - API endpoints
/ \ - Database operations
/ \ - Service interactions
/________________\
Unit Tests (60%)
- Business logic
- Utilities
- Components
```
### 2. Testing Best Practices
#### AAA Pattern (Arrange, Act, Assert)
```typescript
describe('UserService', () => {
it('should create a user successfully', async () => {
// Arrange
const userData = {
email: 'test@example.com',
password: 'SecurePass123!',
};
const mockRepo = createMockRepository();
const service = new UserService(mockRepo);
// Act
const user = await service.createUser(userData);
// Assert
expect(user).toBeDefined();
expect(user.email).toBe(userData.email);
expect(mockRepo.save).toHaveBeenCalledWith(
expect.objectContaining({ email: userData.email })
);
});
});
```
#### Test Data Builders
```typescript
class UserBuilder {
private user: Partial<User> = {
id: '123',
email: 'test@example.com',
name: 'Test User',
role: 'user',
};
withEmail(email: string): this {
this.user.email = email;
return this;
}
withRole(role: UserRole): this {
this.user.role = role;
return this;
}
withVerified(verified = true): this {
this.user.isVerified = verified;
return this;
}
build(): User {
return this.user as User;
}
}
// Usage
const adminUser = new UserBuilder()
.withRole('admin')
.withVerified()
.build();
```
### 3. Test Coverage Goals
- **Overall**: 80%+
- **Critical paths**: 95%+
- **Utilities**: 100%
- **UI Components**: 70%+
- **E2E**: Critical flows only
## Code Quality Standards
### 1. TypeScript Configuration
#### Strict tsconfig.json
```json
{
"compilerOptions": {
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true,
"esModuleInterop": true,
"resolveJsonModule": true
}
}
```
### 2. Code Organization
#### Folder Structure
```
src/
├── components/ # Reusable UI components
│ ├── common/
│ ├── forms/
│ └── layouts/
├── features/ # Feature-based modules
│ ├── auth/
│ │ ├── components/
│ │ ├── hooks/
│ │ ├── services/
│ │ └── types/
│ └── users/
├── hooks/ # Shared React hooks
├── lib/ # Third-party configurations
├── services/ # API and business logic
├── stores/ # State management
├── types/ # TypeScript definitions
├── utils/ # Utility functions
└── config/ # App configuration
```
#### Import Order
```typescript
// 1. External imports
import React from 'react';
import { useQuery } from '@tanstack/react-query';
// 2. Internal aliases
import { Button } from '@/components/common';
import { useAuth } from '@/hooks';
// 3. Relative imports
import { UserCard } from './UserCard';
import styles from './UserList.module.css';
// 4. Type imports
import type { User } from '@/types';
```
### 3. Performance Guidelines
#### React Optimization
```typescript
// Memoization
const ExpensiveComponent = React.memo(({ data }) => {
return <div>{/* Render logic */}</div>;
}, (prevProps, nextProps) => {
// Custom comparison
return prevProps.data.id === nextProps.data.id;
});
// useMemo for expensive calculations
const processedData = useMemo(() => {
return heavyDataProcessing(rawData);
}, [rawData]);
// useCallback for stable references
const handleSubmit = useCallback((values: FormValues) => {
submitForm(values);
}, [submitForm]);
// Code splitting
const AdminPanel = lazy(() => import('./AdminPanel'));
// Virtual scrolling for large lists
import { FixedSizeList } from 'react-window';
function LargeList({ items }) {
return (
<FixedSizeList
height={600}
itemCount={items.length}
itemSize={50}
width="100%"
>
{({ index, style }) => (
<div style={style}>
{items[index].name}
</div>
)}
</FixedSizeList>
);
}
```
#### Database Optimization
```typescript
// Query optimization
// Bad - Multiple queries
const users = await db('users').select('*');
for (const user of users) {
user.posts = await db('posts').where('user_id', user.id);
}
// Good - Single query with join
const users = await db('users')
.leftJoin('posts', 'users.id', 'posts.user_id')
.select('users.*', db.raw('json_agg(posts.*) as posts'))
.groupBy('users.id');
// Indexing strategy
await knex.schema.createTable('users', (table) => {
table.uuid('id').primary();
table.string('email').unique();
table.timestamp('created_at');
// Indexes for common queries
table.index(['email', 'created_at']);
table.index('created_at');
});
// Connection pooling
const db = knex({
client: 'pg',
connection: DATABASE_URL,
pool: {
min: 2,
max: 10,
acquireTimeoutMillis: 30000,
createTimeoutMillis: 30000,
destroyTimeoutMillis: 5000,
idleTimeoutMillis: 30000,
reapIntervalMillis: 1000,
},
});
```
## CI/CD Pipeline
### 1. GitHub Actions Workflow
```yaml
name: CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
env:
NODE_VERSION: '18'
PNPM_VERSION: '8'
jobs:
# Quality checks
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Lint
run: pnpm lint
- name: Type check
run: pnpm type-check
- name: Format check
run: pnpm format:check
# Testing
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:15
env:
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- uses: actions/checkout@v3
- name: Setup environment
uses: ./.github/actions/setup
- name: Run unit tests
run: pnpm test:unit
- name: Run integration tests
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test
run: |
pnpm db:migrate
pnpm test:integration
- name: Upload coverage
uses: codecov/codecov-action@v3
# Build
build:
needs: [quality, test]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup environment
uses: ./.github/actions/setup
- name: Build application
run: pnpm build
- name: Build Docker image
run: docker build -t app:${{ github.sha }} .
- name: Push to registry
if: github.ref == 'refs/heads/main'
run: |
echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
docker push app:${{ github.sha }}
# Deploy
deploy:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: Deploy to production
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.PROD_HOST }}
username: ${{ secrets.PROD_USER }}
key: ${{ secrets.PROD_SSH_KEY }}
script: |
docker pull app:${{ github.sha }}
docker stop app || true
docker rm app || true
docker run -d --name app -p 80:3000 app:${{ github.sha }}
```
### 2. Deployment Checklist
#### Pre-deployment
- [ ] All tests passing
- [ ] Code review approved
- [ ] Database migrations ready
- [ ] Environment variables updated
- [ ] Feature flags configured
- [ ] Monitoring alerts set up
- [ ] Rollback plan prepared
#### Deployment
- [ ] Deploy to staging
- [ ] Run smoke tests
- [ ] Check monitoring dashboards
- [ ] Deploy to production (canary/blue-green)
- [ ] Verify health checks
- [ ] Monitor error rates
#### Post-deployment
- [ ] Verify key metrics
- [ ] Check user feedback
- [ ] Document any issues
- [ ] Update status page
- [ ] Team retrospective
## Monitoring & Observability
### 1. Logging Strategy
```typescript
// Winston logger configuration
import winston from 'winston';
const logger = winston.createLogger({
level: process.env.LOG_LEVEL || 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.errors({ stack: true }),
winston.format.json()
),
defaultMeta: { service: 'api' },
transports: [
new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'combined.log' }),
],
});
if (process.env.NODE_ENV !== 'production') {
logger.add(new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(),
winston.format.simple()
),
}));
}
// Request logging middleware
app.use((req, res, next) => {
const start = Date.now();
res.on('finish', () => {
const duration = Date.now() - start;
logger.info('Request processed', {
method: req.method,
url: req.url,
status: res.statusCode,
duration,
userId: req.user?.id,
ip: req.ip,
userAgent: req.get('user-agent'),
});
});
next();
});
```
### 2. Error Tracking
```typescript
// Sentry integration
import * as Sentry from '@sentry/node';
Sentry.init({
dsn: process.env.SENTRY_DSN,
environment: process.env.NODE_ENV,
integrations: [
new Sentry.Integrations.Http({ tracing: true }),
new Sentry.Integrations.Express({ app }),
],
tracesSampleRate: process.env.NODE_ENV === 'production' ? 0.1 : 1.0,
beforeSend(event, hint) {
// Filter sensitive data
if (event.request?.cookies) {
delete event.request.cookies;
}
return event;
},
});
// Error boundary for React
class ErrorBoundary extends React.Component {
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
Sentry.withScope((scope) => {
scope.setExtras(errorInfo);
Sentry.captureException(error);
});
}
render() {
if (this.state.hasError) {
return <ErrorFallback />;
}
return this.props.children;
}
}
```
### 3. Performance Monitoring
```typescript
// Custom metrics with Prometheus
import { register, Counter, Histogram, Gauge } from 'prom-client';
const httpRequestDuration = new Histogram({
name: 'http_request_duration_seconds',
help: 'Duration of HTTP requests in seconds',
labelNames: ['method', 'route', 'status'],
});
const activeConnections = new Gauge({
name: 'active_connections',
help: 'Number of active connections',
});
const requestCounter = new Counter({
name: 'http_requests_total',
help: 'Total number of HTTP requests',
labelNames: ['method', 'route', 'status'],
});
// Metrics endpoint
app.get('/metrics', async (req, res) => {
res.set('Content-Type', register.contentType);
res.end(await register.metrics());
});
```
## Security Best Practices
### 1. Authentication & Authorization
```typescript
// Secure password hashing
import bcrypt from 'bcryptjs';
const SALT_ROUNDS = 12;
export async function hashPassword(password: string): Promise<string> {
return bcrypt.hash(password, SALT_ROUNDS);
}
export async function verifyPassword(
password: string,
hash: string
): Promise<boolean> {
return bcrypt.compare(password, hash);
}
// JWT with refresh tokens
interface TokenPair {
accessToken: string;
refreshToken: string;
}
export function generateTokens(userId: string): TokenPair {
const accessToken = jwt.sign(
{ sub: userId },
process.env.JWT_SECRET!,
{ expiresIn: '15m' }
);
const refreshToken = jwt.sign(
{ sub: userId },
process.env.JWT_REFRESH_SECRET!,
{ expiresIn: '7d' }
);
return { accessToken, refreshToken };
}
// Session management with Redis
async function createSession(userId: string): Promise<string> {
const sessionId = crypto.randomUUID();
const sessionData = {
userId,
createdAt: Date.now(),
lastActivity: Date.now(),
};
await redis.setex(
`session:${sessionId}`,
3600, // 1 hour
JSON.stringify(sessionData)
);
return sessionId;
}
```
### 2. Input Validation & Sanitization
```typescript
// Input validation with Zod
import { z } from 'zod';
import DOMPurify from 'isomorphic-dompurify';
const UserInputSchema = z.object({
email: z.string().email().toLowerCase(),
username: z.string()
.min(3)
.max(20)
.regex(/^[a-zA-Z0-9_]+$/, 'Username can only contain letters, numbers, and underscores'),
bio: z.string()
.max(500)
.transform(val => DOMPurify.sanitize(val)), // Sanitize HTML
age: z.number().int().positive().max(150),
website: z.string().url().optional(),
});
// SQL injection prevention with parameterized queries
// Never do this:
const query = `SELECT * FROM users WHERE email = '${email}'`;
// Always do this:
const user = await db('users').where({ email }).first();
// Or with raw queries:
const user = await db.raw(
'SELECT * FROM users WHERE email = ?',
[email]
);
```
### 3. Security Headers
```typescript
import helmet from 'helmet';
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
scriptSrc: ["'self'"],
imgSrc: ["'self'", "data:", "https:"],
connectSrc: ["'self'"],
fontSrc: ["'self'"],
objectSrc: ["'none'"],
mediaSrc: ["'self'"],
frameSrc: ["'none'"],
},
},
crossOriginEmbedderPolicy: true,
crossOriginOpenerPolicy: true,
crossOriginResourcePolicy: { policy: "cross-origin" },
dnsPrefetchControl: true,
frameguard: { action: 'deny' },
hidePoweredBy: true,
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true,
},
ieNoOpen: true,
noSniff: true,
originAgentCluster: true,
permittedCrossDomainPolicies: false,
referrerPolicy: { policy: "no-referrer" },
xssFilter: true,
}));
```
## Documentation Standards
### 1. API Documentation
```typescript
/**
* @swagger
* /api/users:
* get:
* summary: Get all users
* tags: [Users]
* parameters:
* - in: query
* name: page
* schema:
* type: integer
* default: 1
* description: Page number
* - in: query
* name: limit
* schema:
* type: integer
* default: 10
* description: Items per page
* responses:
* 200:
* description: List of users
* content:
* application/json:
* schema:
* type: object
* properties:
* users:
* type: array
* items:
* $ref: '#/components/schemas/User'
* meta:
* $ref: '#/components/schemas/PaginationMeta'
* 401:
* description: Unauthorized
*/
router.get('/users', authenticate, userController.getUsers);
```
### 2. Code Documentation
```typescript
/**
* Processes payment for an order
*
* @param orderId - The unique order identifier
* @param paymentMethod - Payment method details
* @returns Payment result with transaction ID
* @throws {PaymentError} When payment processing fails
* @throws {ValidationError} When input validation fails
*
* @example
* ```typescript
* const result = await processPayment('order-123', {
* type: 'card',
* token: 'tok_visa',
* });
* console.log(result.transactionId);
* ```
*/
export async function processPayment(
orderId: string,
paymentMethod: PaymentMethod
): Promise<PaymentResult> {
// Implementation
}
```
### 3. README Template
```markdown
# Project Name
Brief description of the project.
## 🚀 Features
- Feature 1
- Feature 2
- Feature 3
## 📋 Prerequisites
- Node.js 18+
- PostgreSQL 15+
- Redis 7+
## 🔧 Installation
\`\`\`bash
# Clone repository
git clone https://github.com/username/project.git
# Install dependencies
pnpm install
# Setup environment
cp .env.example .env
# Run migrations
pnpm db:migrate
# Start development
pnpm dev
\`\`\`
## 🧪 Testing
\`\`\`bash
# Unit tests
pnpm test:unit
# Integration tests
pnpm test:integration
# E2E tests
pnpm test:e2e
# All tests with coverage
pnpm test:coverage
\`\`\`
## 📚 Documentation
- [API Documentation](./docs/api.md)
- [Architecture Guide](./docs/architecture.md)
- [Contributing Guide](./CONTRIBUTING.md)
## 📄 License
MIT
```