# Technology Patterns Reference This file contains best practices and patterns for each supported technology. Reference this when generating skills. --- ## Fullstack Technologies ### PostgreSQL **Schema Design Patterns:** ```sql -- Use UUIDs for public-facing IDs CREATE TABLE users ( id SERIAL PRIMARY KEY, public_id UUID DEFAULT gen_random_uuid() UNIQUE NOT NULL, email VARCHAR(255) UNIQUE NOT NULL, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); -- Partial indexes for common queries CREATE INDEX CONCURRENTLY idx_users_active ON users (email) WHERE deleted_at IS NULL; -- Composite indexes for multi-column queries CREATE INDEX idx_orders_user_status ON orders (user_id, status, created_at DESC); ``` **Query Optimization:** ```sql -- Always use EXPLAIN ANALYZE EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT) SELECT * FROM users WHERE email = 'test@example.com'; -- Use CTEs for readability but be aware of optimization barriers WITH active_users AS MATERIALIZED ( SELECT id FROM users WHERE last_login > NOW() - INTERVAL '30 days' ) SELECT * FROM orders WHERE user_id IN (SELECT id FROM active_users); ``` **Connection Pooling:** - Use PgBouncer for connection pooling - Set `pool_mode = transaction` for Django - Monitor with `pgbouncer SHOW POOLS` --- ### Django **Model Patterns:** ```python from django.db import models from django.db.models import Manager, QuerySet class ActiveManager(Manager): def get_queryset(self) -> QuerySet: return super().get_queryset().filter(is_active=True) class BaseModel(models.Model): created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: abstract = True class User(BaseModel): email = models.EmailField(unique=True, db_index=True) is_active = models.BooleanField(default=True, db_index=True) objects = Manager() active = ActiveManager() class Meta: ordering = ['-created_at'] indexes = [ models.Index(fields=['email', 'is_active']), ] constraints = [ models.CheckConstraint( check=models.Q(email__icontains='@'), name='valid_email_format' ), ] ``` **QuerySet Optimization:** ```python # Always use select_related for ForeignKey User.objects.select_related('profile').get(id=1) # Use prefetch_related for reverse relations and M2M User.objects.prefetch_related( Prefetch( 'orders', queryset=Order.objects.filter(status='completed').select_related('product') ) ).all() # Use only() or defer() for partial loading User.objects.only('id', 'email').filter(is_active=True) # Use values() or values_list() when you don't need model instances User.objects.values_list('email', flat=True) ``` **Middleware Pattern:** ```python class RequestTimingMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): start_time = time.monotonic() response = self.get_response(request) duration = time.monotonic() - start_time response['X-Request-Duration'] = f'{duration:.3f}s' return response ``` --- ### REST API (DRF) **Serializer Patterns:** ```python from rest_framework import serializers class UserSerializer(serializers.ModelSerializer): full_name = serializers.SerializerMethodField() class Meta: model = User fields = ['id', 'email', 'full_name', 'created_at'] read_only_fields = ['id', 'created_at'] def get_full_name(self, obj) -> str: return f'{obj.first_name} {obj.last_name}'.strip() def validate_email(self, value: str) -> str: if User.objects.filter(email=value).exists(): raise serializers.ValidationError('Email already exists') return value.lower() class CreateUserSerializer(serializers.ModelSerializer): password = serializers.CharField(write_only=True, min_length=8) class Meta: model = User fields = ['email', 'password'] def create(self, validated_data): return User.objects.create_user(**validated_data) ``` **View Patterns:** ```python from rest_framework import status from rest_framework.decorators import api_view, permission_classes from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from drf_spectacular.utils import extend_schema, OpenApiParameter @extend_schema( parameters=[ OpenApiParameter('status', str, description='Filter by status'), ], responses={200: OrderSerializer(many=True)}, tags=['orders'], ) @api_view(['GET']) @permission_classes([IsAuthenticated]) def list_orders(request): """List all orders for the authenticated user.""" orders = Order.objects.filter(user=request.user) status_filter = request.query_params.get('status') if status_filter: orders = orders.filter(status=status_filter) serializer = OrderSerializer(orders, many=True) return Response(serializer.data) ``` **Error Response Format:** ```python # Standard error response { "error": { "code": "VALIDATION_ERROR", "message": "Invalid input data", "details": { "email": ["This field is required."], "password": ["Password must be at least 8 characters."] } } } # Custom exception handler def custom_exception_handler(exc, context): response = exception_handler(exc, context) if response is not None: response.data = { 'error': { 'code': exc.__class__.__name__.upper(), 'message': str(exc), 'details': response.data if isinstance(response.data, dict) else {} } } return response ``` --- ### Next.js **App Router Patterns:** ```typescript // app/users/[id]/page.tsx import { notFound } from 'next/navigation'; interface Props { params: { id: string }; } // Generate static params for SSG export async function generateStaticParams() { const users = await getUsers(); return users.map((user) => ({ id: user.id.toString() })); } // Metadata generation export async function generateMetadata({ params }: Props) { const user = await getUser(params.id); return { title: user?.name ?? 'User Not Found', description: user?.bio, }; } // Page component (Server Component by default) export default async function UserPage({ params }: Props) { const user = await getUser(params.id); if (!user) { notFound(); } return ; } ``` **Data Fetching:** ```typescript // With caching and revalidation async function getUser(id: string) { const res = await fetch(`${API_URL}/users/${id}`, { next: { revalidate: 60, // Revalidate every 60 seconds tags: [`user-${id}`], // For on-demand revalidation }, }); if (!res.ok) return null; return res.json(); } // Server action for mutations 'use server'; import { revalidateTag } from 'next/cache'; export async function updateUser(id: string, data: FormData) { const response = await fetch(`${API_URL}/users/${id}`, { method: 'PATCH', body: JSON.stringify(Object.fromEntries(data)), }); if (!response.ok) { throw new Error('Failed to update user'); } revalidateTag(`user-${id}`); return response.json(); } ``` **Middleware:** ```typescript // middleware.ts import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; export function middleware(request: NextRequest) { // Authentication check const token = request.cookies.get('auth-token'); if (!token && request.nextUrl.pathname.startsWith('/dashboard')) { return NextResponse.redirect(new URL('/login', request.url)); } // Add headers const response = NextResponse.next(); response.headers.set('x-request-id', crypto.randomUUID()); return response; } export const config = { matcher: ['/dashboard/:path*', '/api/:path*'], }; ``` --- ### React **Component Patterns:** ```tsx import { forwardRef, memo, useCallback, useMemo } from 'react'; interface ButtonProps extends React.ButtonHTMLAttributes { variant?: 'primary' | 'secondary'; isLoading?: boolean; } export const Button = memo(forwardRef( ({ variant = 'primary', isLoading, children, disabled, ...props }, ref) => { const className = useMemo( () => `btn btn-${variant} ${isLoading ? 'btn-loading' : ''}`, [variant, isLoading] ); return ( ); } )); Button.displayName = 'Button'; ``` **Custom Hooks:** ```tsx function useAsync(asyncFn: () => Promise, deps: unknown[] = []) { const [state, setState] = useState<{ data: T | null; error: Error | null; isLoading: boolean; }>({ data: null, error: null, isLoading: true, }); useEffect(() => { let isMounted = true; setState(prev => ({ ...prev, isLoading: true })); asyncFn() .then(data => { if (isMounted) { setState({ data, error: null, isLoading: false }); } }) .catch(error => { if (isMounted) { setState({ data: null, error, isLoading: false }); } }); return () => { isMounted = false; }; }, deps); return state; } ``` --- ### Celery **Task Configuration:** ```python # celery.py from celery import Celery app = Celery('myapp') app.conf.update( # Broker settings broker_url='redis://localhost:6379/0', result_backend='redis://localhost:6379/1', # Task settings task_serializer='json', accept_content=['json'], result_serializer='json', timezone='UTC', enable_utc=True, # Performance worker_prefetch_multiplier=4, task_acks_late=True, task_reject_on_worker_lost=True, # Results result_expires=86400, # 24 hours # Retry task_default_retry_delay=60, task_max_retries=3, # Beat schedule beat_schedule={ 'cleanup-daily': { 'task': 'tasks.cleanup', 'schedule': crontab(hour=2, minute=0), }, }, ) ``` **Task Patterns:** ```python from celery import shared_task, chain, group, chord from celery.exceptions import MaxRetriesExceededError @shared_task( bind=True, name='process.item', max_retries=3, autoretry_for=(ConnectionError,), retry_backoff=True, retry_backoff_max=600, time_limit=300, soft_time_limit=240, ) def process_item(self, item_id: int) -> dict: """Process a single item with automatic retry.""" try: item = Item.objects.get(id=item_id) result = do_processing(item) return {'status': 'success', 'item_id': item_id, 'result': result} except Item.DoesNotExist: return {'status': 'not_found', 'item_id': item_id} except SoftTimeLimitExceeded: self.retry(countdown=60) def process_batch(item_ids: list[int]) -> None: """Process items in parallel then aggregate.""" workflow = chord( group(process_item.s(item_id) for item_id in item_ids), aggregate_results.s() ) workflow.apply_async() ``` --- ### Redis **Caching Patterns:** ```python import json from functools import wraps from typing import Callable, TypeVar import redis T = TypeVar('T') client = redis.Redis(host='localhost', port=6379, db=0, decode_responses=True) def cache(ttl: int = 3600, prefix: str = 'cache'): """Decorator for caching function results.""" def decorator(func: Callable[..., T]) -> Callable[..., T]: @wraps(func) def wrapper(*args, **kwargs) -> T: # Generate cache key key_parts = [prefix, func.__name__] + [str(a) for a in args] key = ':'.join(key_parts) # Try cache cached = client.get(key) if cached: return json.loads(cached) # Execute and cache result = func(*args, **kwargs) client.setex(key, ttl, json.dumps(result)) return result wrapper.invalidate = lambda *args: client.delete( ':'.join([prefix, func.__name__] + [str(a) for a in args]) ) return wrapper return decorator # Rate limiting def is_rate_limited(key: str, limit: int, window: int) -> bool: """Check if action is rate limited using sliding window.""" pipe = client.pipeline() now = time.time() window_start = now - window pipe.zremrangebyscore(key, 0, window_start) pipe.zadd(key, {str(now): now}) pipe.zcard(key) pipe.expire(key, window) results = pipe.execute() return results[2] > limit ``` --- ## DevOps Technologies ### GitLab CI/CD **Pipeline Structure:** ```yaml stages: - test - build - deploy variables: DOCKER_TLS_CERTDIR: "/certs" PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" .python_cache: &python_cache cache: key: ${CI_COMMIT_REF_SLUG} paths: - .cache/pip - .venv/ test: stage: test image: python:3.12 <<: *python_cache before_script: - python -m venv .venv - source .venv/bin/activate - pip install -r requirements-dev.txt script: - pytest --cov --cov-report=xml coverage: '/TOTAL.*\s+(\d+%)$/' artifacts: reports: coverage_report: coverage_format: cobertura path: coverage.xml build: stage: build image: docker:24.0 services: - docker:24.0-dind script: - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA . - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH deploy:production: stage: deploy image: bitnami/kubectl:latest script: - kubectl set image deployment/app app=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA environment: name: production url: https://app.example.com rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH when: manual ``` --- ### Docker Compose **Production-Ready Pattern:** ```yaml version: '3.8' services: app: build: context: . target: production args: - BUILDKIT_INLINE_CACHE=1 image: ${IMAGE_NAME:-app}:${IMAGE_TAG:-latest} restart: unless-stopped depends_on: db: condition: service_healthy redis: condition: service_healthy environment: - DATABASE_URL=postgres://user:pass@db:5432/app - REDIS_URL=redis://redis:6379/0 healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health/"] interval: 30s timeout: 10s retries: 3 start_period: 40s deploy: resources: limits: cpus: '1' memory: 512M reservations: cpus: '0.25' memory: 128M logging: driver: json-file options: max-size: "10m" max-file: "3" db: image: postgres:15-alpine restart: unless-stopped volumes: - postgres_data:/var/lib/postgresql/data environment: - POSTGRES_USER=user - POSTGRES_PASSWORD=pass - POSTGRES_DB=app healthcheck: test: ["CMD-SHELL", "pg_isready -U user -d app"] interval: 10s timeout: 5s retries: 5 redis: image: redis:7-alpine restart: unless-stopped command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 volumes: postgres_data: redis_data: networks: default: driver: bridge ``` --- ### Kubernetes/K3s **Deployment Best Practices:** ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: app spec: replicas: 3 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 selector: matchLabels: app: app template: spec: terminationGracePeriodSeconds: 30 containers: - name: app image: app:latest ports: - containerPort: 8000 resources: requests: cpu: 100m memory: 128Mi limits: cpu: 500m memory: 256Mi livenessProbe: httpGet: path: /health/live/ port: 8000 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /health/ready/ port: 8000 initialDelaySeconds: 5 periodSeconds: 5 lifecycle: preStop: exec: command: ["/bin/sh", "-c", "sleep 10"] ``` --- ### Prometheus **Alert Rule Patterns:** ```yaml groups: - name: slo.rules rules: # Error budget burn rate - alert: ErrorBudgetBurnRate expr: | ( sum(rate(http_requests_total{status=~"5.."}[1h])) / sum(rate(http_requests_total[1h])) ) > (14.4 * (1 - 0.999)) for: 5m labels: severity: critical annotations: summary: "Error budget burning too fast" description: "At current error rate, monthly error budget will be exhausted in {{ $value | humanize }}" # Availability SLO - record: slo:availability:ratio expr: | 1 - ( sum(rate(http_requests_total{status=~"5.."}[30d])) / sum(rate(http_requests_total[30d])) ) ``` --- ### Grafana **Dashboard Variables:** ```json { "templating": { "list": [ { "name": "namespace", "type": "query", "query": "label_values(kube_pod_info, namespace)", "refresh": 2, "includeAll": true, "multi": true }, { "name": "pod", "type": "query", "query": "label_values(kube_pod_info{namespace=~\"$namespace\"}, pod)", "refresh": 2, "includeAll": true, "multi": true } ] } } ``` --- ### Nginx **Reverse Proxy Pattern:** ```nginx upstream backend { least_conn; server backend1:8000 weight=3; server backend2:8000 weight=2; server backend3:8000 backup; keepalive 32; } server { listen 443 ssl http2; server_name api.example.com; ssl_certificate /etc/ssl/certs/cert.pem; ssl_certificate_key /etc/ssl/private/key.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; # Security headers add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; location /api/ { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # Timeouts proxy_connect_timeout 10s; proxy_send_timeout 60s; proxy_read_timeout 60s; # Buffering proxy_buffering on; proxy_buffer_size 4k; proxy_buffers 8 4k; } location /static/ { alias /var/www/static/; expires 30d; add_header Cache-Control "public, immutable"; gzip_static on; } } ``` --- ### Traefik **IngressRoute Pattern:** ```yaml apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: app spec: entryPoints: - websecure routes: - match: Host(`app.example.com`) && PathPrefix(`/api`) kind: Rule services: - name: app-api port: 8000 weight: 100 middlewares: - name: rate-limit - name: retry - match: Host(`app.example.com`) kind: Rule services: - name: app-frontend port: 3000 tls: certResolver: letsencrypt options: name: modern-tls --- apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: rate-limit spec: rateLimit: average: 100 period: 1m burst: 50 --- apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: retry spec: retry: attempts: 3 initialInterval: 100ms ```