Quality Templates
Ready-to-use quality assurance templates for GISE methodology. These templates help establish consistent quality standards and automated checks across your projects.
Linting and Formatting Templates
ESLint Configuration Template
Use When: Setting up TypeScript projects with comprehensive linting
// .eslintrc.js
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 2022,
sourceType: 'module',
project: './tsconfig.json'
},
plugins: [
'@typescript-eslint',
'security',
'jest',
'import',
'unused-imports'
],
extends: [
'eslint:recommended',
'@typescript-eslint/recommended',
'@typescript-eslint/recommended-requiring-type-checking',
'plugin:security/recommended',
'plugin:jest/recommended',
'plugin:import/typescript',
'prettier'
],
rules: {
// TypeScript specific
'@typescript-eslint/no-unused-vars': 'error',
'@typescript-eslint/explicit-function-return-type': 'warn',
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/prefer-nullish-coalescing': 'error',
'@typescript-eslint/prefer-optional-chain': 'error',
'@typescript-eslint/strict-boolean-expressions': 'error',
'@typescript-eslint/prefer-readonly': 'error',
'@typescript-eslint/no-floating-promises': 'error',
// Code quality
'complexity': ['error', 10],
'max-lines': ['error', 300],
'max-lines-per-function': ['error', 50],
'max-depth': ['error', 4],
'max-params': ['error', 4],
'no-console': 'warn',
'no-debugger': 'error',
'prefer-const': 'error',
'no-var': 'error',
'eqeqeq': 'error',
'curly': 'error',
'no-duplicate-imports': 'error',
// Import organization
'import/order': ['error', {
'groups': [
'builtin',
'external',
'internal',
'parent',
'sibling',
'index'
],
'newlines-between': 'always',
'alphabetize': {
'order': 'asc',
'caseInsensitive': true
}
}],
'unused-imports/no-unused-imports': 'error',
// Security
'security/detect-object-injection': 'error',
'security/detect-non-literal-regexp': 'error',
'security/detect-possible-timing-attacks': 'error',
'security/detect-unsafe-regex': 'error'
},
env: {
node: true,
jest: true,
es2022: true
},
overrides: [
{
files: ['*.test.ts', '*.spec.ts'],
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'max-lines': 'off'
}
}
]
};
Prettier Configuration Template
Use When: Enforcing consistent code formatting
{
"semi": true,
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"bracketSpacing": true,
"arrowParens": "avoid",
"endOfLine": "lf",
"bracketSameLine": false,
"quoteProps": "as-needed",
"jsxSingleQuote": true,
"overrides": [
{
"files": "*.md",
"options": {
"printWidth": 80,
"proseWrap": "always"
}
},
{
"files": "*.yml",
"options": {
"tabWidth": 2,
"singleQuote": false
}
}
]
}
TypeScript Quality Templates
Strict TypeScript Configuration
Use When: Setting up TypeScript with maximum type safety
{
"compilerOptions": {
"target": "ES2022",
"module": "commonjs",
"lib": ["ES2022", "DOM"],
"outDir": "./dist",
"rootDir": "./src",
// Type Checking
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialization": true,
"noImplicitThis": true,
"useUnknownInCatchVariables": true,
"alwaysStrict": true,
// Additional Checks
"noUnusedLocals": true,
"noUnusedParameters": true,
"exactOptionalPropertyTypes": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
// Module Resolution
"moduleResolution": "node",
"baseUrl": "./src",
"paths": {
"@/*": ["*"],
"@/types/*": ["types/*"],
"@/utils/*": ["utils/*"],
"@/services/*": ["services/*"]
},
"resolveJsonModule": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
// Emit
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"removeComments": false,
"importHelpers": true,
// Experimental
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
// Advanced
"skipLibCheck": true,
"incremental": true,
"tsBuildInfoFile": "./dist/.tsbuildinfo"
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
"dist",
"**/*.test.ts",
"**/*.spec.ts",
"coverage"
]
}
Testing Quality Templates
Jest Configuration Template
Use When: Setting up comprehensive Jest testing environment
// jest.config.js
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
roots: ['<rootDir>/src', '<rootDir>/tests'],
testMatch: [
'**/__tests__/**/*.(ts|js)',
'**/*.(test|spec).(ts|js)'
],
transform: {
'^.+\\.(ts|tsx)$': 'ts-jest'
},
collectCoverageFrom: [
'src/**/*.(ts|js)',
'!src/**/*.d.ts',
'!src/**/*.test.(ts|js)',
'!src/**/*.spec.(ts|js)',
'!src/index.ts'
],
coverageDirectory: 'coverage',
coverageReporters: [
'text',
'lcov',
'html',
'json-summary'
],
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80
}
},
setupFilesAfterEnv: [
'<rootDir>/tests/setup.ts'
],
moduleNameMapping: {
'^@/(.*)$': '<rootDir>/src/$1'
},
testTimeout: 10000,
verbose: true,
clearMocks: true,
restoreMocks: true
};
Test Setup Template
Use When: Configuring Jest test environment
// tests/setup.ts
import 'reflect-metadata';
import { Container } from 'inversify';
// Global test setup
beforeAll(async () => {
// Set test environment variables
process.env.NODE_ENV = 'test';
process.env.JWT_SECRET = 'test-jwt-secret';
process.env.DATABASE_URL = 'postgresql://test:test@localhost:5432/test_db';
// Mock console methods in tests
jest.spyOn(console, 'log').mockImplementation(() => {});
jest.spyOn(console, 'info').mockImplementation(() => {});
jest.spyOn(console, 'warn').mockImplementation(() => {});
jest.spyOn(console, 'error').mockImplementation(() => {});
});
afterAll(async () => {
// Cleanup global resources
Container.unbindAll();
// Restore console methods
jest.restoreAllMocks();
});
beforeEach(() => {
// Reset container before each test
Container.snapshot();
});
afterEach(() => {
// Restore container after each test
Container.restore();
// Clear all mocks
jest.clearAllMocks();
});
// Global test utilities
global.testUtils = {
delay: (ms: number) => new Promise(resolve => setTimeout(resolve, ms)),
mockAsync: <T>(returnValue: T, delay = 0) =>
jest.fn().mockImplementation(() =>
new Promise(resolve => setTimeout(() => resolve(returnValue), delay))
),
mockAsyncError: (error: Error, delay = 0) =>
jest.fn().mockImplementation(() =>
new Promise((_, reject) => setTimeout(() => reject(error), delay))
)
};
// Extend Jest matchers
declare global {
namespace jest {
interface Matchers<R> {
toBeValidUuid(): R;
toBeValidEmail(): R;
toBeValidDate(): R;
}
}
var testUtils: {
delay: (ms: number) => Promise<void>;
mockAsync: <T>(returnValue: T, delay?: number) => jest.MockedFunction<() => Promise<T>>;
mockAsyncError: (error: Error, delay?: number) => jest.MockedFunction<() => Promise<never>>;
};
}
expect.extend({
toBeValidUuid(received: string) {
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
const pass = uuidRegex.test(received);
return {
message: () => `expected ${received} ${pass ? 'not ' : ''}to be a valid UUID`,
pass
};
},
toBeValidEmail(received: string) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const pass = emailRegex.test(received);
return {
message: () => `expected ${received} ${pass ? 'not ' : ''}to be a valid email`,
pass
};
},
toBeValidDate(received: string) {
const date = new Date(received);
const pass = !isNaN(date.getTime());
return {
message: () => `expected ${received} ${pass ? 'not ' : ''}to be a valid date`,
pass
};
}
});
Security Quality Templates
Security Headers Template
Use When: Implementing security middleware
// src/middleware/security.ts
import helmet from 'helmet';
import rateLimit from 'express-rate-limit';
import { Request, Response, NextFunction } from 'express';
// Security headers middleware
export const securityHeaders = helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'", 'https://fonts.googleapis.com'],
scriptSrc: ["'self'"],
fontSrc: ["'self'", 'https://fonts.gstatic.com'],
imgSrc: ["'self'", 'data:', 'https:'],
connectSrc: ["'self'"],
frameSrc: ["'none'"],
objectSrc: ["'none'"],
mediaSrc: ["'self'"],
upgradeInsecureRequests: []
}
},
hsts: {
maxAge: 31536000, // 1 year
includeSubDomains: true,
preload: true
},
noSniff: true,
xssFilter: true,
referrerPolicy: { policy: 'same-origin' },
frameguard: { action: 'deny' }
});
// Rate limiting middleware
export const rateLimiters = {
general: rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
message: {
error: 'Too many requests from this IP, please try again later.'
},
standardHeaders: true,
legacyHeaders: false
}),
auth: rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 5, // limit each IP to 5 auth requests per windowMs
message: {
error: 'Too many authentication attempts, please try again later.'
},
standardHeaders: true,
legacyHeaders: false
}),
api: rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 1000, // limit each IP to 1000 API requests per windowMs
message: {
error: 'API rate limit exceeded, please try again later.'
},
standardHeaders: true,
legacyHeaders: false
})
};
// Input sanitization middleware
export const sanitizeInput = (req: Request, res: Response, next: NextFunction) => {
// Remove potentially dangerous characters
const sanitize = (obj: any): any => {
if (typeof obj === 'string') {
return obj
.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
.replace(/javascript:/gi, '')
.replace(/on\w+\s*=/gi, '');
}
if (Array.isArray(obj)) {
return obj.map(sanitize);
}
if (typeof obj === 'object' && obj !== null) {
const sanitized: any = {};
for (const [key, value] of Object.entries(obj)) {
sanitized[key] = sanitize(value);
}
return sanitized;
}
return obj;
};
req.body = sanitize(req.body);
req.query = sanitize(req.query);
req.params = sanitize(req.params);
next();
};
Performance Quality Templates
Performance Monitoring Template
Use When: Implementing application performance monitoring
// src/middleware/performance.ts
import { Request, Response, NextFunction } from 'express';
import promClient from 'prom-client';
// Create performance metrics
const httpRequestDuration = new promClient.Histogram({
name: 'http_request_duration_seconds',
help: 'Duration of HTTP requests in seconds',
labelNames: ['method', 'route', 'status_code'],
buckets: [0.1, 0.3, 0.5, 0.7, 1, 3, 5, 7, 10]
});
const httpRequestsTotal = new promClient.Counter({
name: 'http_requests_total',
help: 'Total number of HTTP requests',
labelNames: ['method', 'route', 'status_code']
});
const activeConnections = new promClient.Gauge({
name: 'http_active_connections',
help: 'Number of active HTTP connections'
});
const memoryUsage = new promClient.Gauge({
name: 'nodejs_memory_usage_bytes',
help: 'Node.js memory usage in bytes',
labelNames: ['type']
});
const eventLoopLag = new promClient.Gauge({
name: 'nodejs_eventloop_lag_seconds',
help: 'Event loop lag in seconds'
});
// Performance monitoring middleware
export const performanceMonitoring = (req: Request, res: Response, next: NextFunction) => {
const start = Date.now();
activeConnections.inc();
res.on('finish', () => {
const duration = (Date.now() - start) / 1000;
const route = req.route?.path || req.path;
const labels = {
method: req.method,
route,
status_code: res.statusCode.toString()
};
httpRequestDuration.observe(labels, duration);
httpRequestsTotal.inc(labels);
activeConnections.dec();
// Log slow requests
if (duration > 1) {
console.warn(`Slow request detected: ${req.method} ${route} took ${duration}s`);
}
});
next();
};
// System metrics collection
export const collectSystemMetrics = () => {
setInterval(() => {
const usage = process.memoryUsage();
memoryUsage.set({ type: 'rss' }, usage.rss);
memoryUsage.set({ type: 'heapTotal' }, usage.heapTotal);
memoryUsage.set({ type: 'heapUsed' }, usage.heapUsed);
memoryUsage.set({ type: 'external' }, usage.external);
// Measure event loop lag
const start = process.hrtime.bigint();
setImmediate(() => {
const lag = Number(process.hrtime.bigint() - start) / 1e9;
eventLoopLag.set(lag);
});
}, 5000);
};
// Metrics endpoint handler
export const metricsHandler = (req: Request, res: Response) => {
res.set('Content-Type', promClient.register.contentType);
res.send(promClient.register.metrics());
};
Code Quality Checklist Template
Pre-commit Checklist
Use When: Ensuring code quality before commits
## Code Quality Checklist
### Before Committing
- [ ] Code follows project style guidelines
- [ ] All tests pass locally
- [ ] No linting errors or warnings
- [ ] TypeScript compilation successful
- [ ] Security scan passed
- [ ] Performance impact assessed
- [ ] Documentation updated if needed
- [ ] No sensitive data in code
- [ ] Error handling implemented
- [ ] Logging added for important operations
### Code Review Checklist
- [ ] Code is readable and maintainable
- [ ] Business logic is correct
- [ ] Edge cases are handled
- [ ] Error scenarios are covered
- [ ] Security considerations addressed
- [ ] Performance implications evaluated
- [ ] Tests are comprehensive
- [ ] Documentation is accurate
- [ ] API contracts maintained
- [ ] Dependencies are justified
### AI-Assisted Code Review
- [ ] AI-generated code reviewed by human
- [ ] AI suggestions validated against requirements
- [ ] Code follows established patterns
- [ ] No AI-specific anti-patterns
- [ ] Business context properly incorporated
- [ ] Security implications considered
- [ ] Performance characteristics validated
Package.json Scripts Template
Use When: Setting up quality assurance npm scripts
{
"scripts": {
"dev": "tsx watch src/server.ts",
"build": "tsc && tsc-alias",
"start": "node dist/server.js",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"test:integration": "jest --testPathPattern=integration",
"test:e2e": "jest --testPathPattern=e2e",
"lint": "eslint src --ext .ts,.tsx",
"lint:fix": "eslint src --ext .ts,.tsx --fix",
"lint:ci": "eslint src --ext .ts,.tsx --format json --output-file eslint-report.json",
"format": "prettier --write src/**/*.{ts,tsx,json,md}",
"format:check": "prettier --check src/**/*.{ts,tsx,json,md}",
"type-check": "tsc --noEmit",
"type-check:watch": "tsc --noEmit --watch",
"security": "audit-ci --config .audit-ci.json",
"security:fix": "npm audit fix",
"quality": "npm run lint && npm run type-check && npm run test:coverage && npm run security",
"quality:ci": "npm run lint:ci && npm run type-check && npm run test:coverage && npm run security",
"clean": "rimraf dist coverage .nyc_output eslint-report.json",
"reinstall": "npm run clean && rm -rf node_modules package-lock.json && npm install",
"prepare": "husky install",
"pre-commit": "lint-staged",
"pre-push": "npm run quality"
}
}
Related Resources
Next: Configuration Files | Security Templates
Quality is not an accident; it is always the result of intelligent effort and systematic processes.