Skip to content
Back to skills

285 Development Workflows Fbe5eb0f

ASecurity

Complete development lifecycle workflows from local setup to production deployment. ---

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 11, 2026
devopstypescriptgobashsqlreactnextjsnodedockertestingcode-review

Works with

  • cli
  • api

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 285-development_workflows_fbe5eb0f --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 285 Development Workflows Fbe5eb0f?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 285 Development Workflows Fbe5eb0f
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-285-development-workflows-fbe5eb0f/badge)](https://www.skillsdirectory.com/skills/tools-only-285-development-workflows-fbe5eb0f)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# Fullstack Development Workflows

Complete development lifecycle workflows from local setup to production deployment.

---

## Table of Contents

- [Local Development Setup](#local-development-setup)
- [Git Workflows](#git-workflows)
- [CI/CD Pipelines](#cicd-pipelines)
- [Testing Strategies](#testing-strategies)
- [Code Review Process](#code-review-process)
- [Deployment Strategies](#deployment-strategies)
- [Monitoring and Observability](#monitoring-and-observability)

---

## Local Development Setup

### Docker Compose Development Environment

```yaml
# docker-compose.yml
version: "3.8"

services:
  app:
    build:
      context: .
      target: development
    volumes:
      - .:/app
      - /app/node_modules
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/app
      - REDIS_URL=redis://redis:6379
    depends_on:
      - db
      - redis

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: app
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"

volumes:
  postgres_data:
```

**Multistage Dockerfile:**

```dockerfile
# Base stage
FROM node:20-alpine AS base
WORKDIR /app
RUN apk add --no-cache libc6-compat

# Development stage
FROM base AS development
COPY package*.json ./
RUN npm ci
COPY . .
CMD ["npm", "run", "dev"]

# Builder stage
FROM base AS builder
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Production stage
FROM base AS production
ENV NODE_ENV=production
COPY --from=builder /app/package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
USER node
CMD ["node", "dist/index.js"]
```

### Environment Configuration

```bash
# .env.local (development)
DATABASE_URL="postgresql://user:pass@localhost:5432/app_dev"
REDIS_URL="redis://localhost:6379"
JWT_SECRET="development-secret-change-in-prod"
LOG_LEVEL="debug"

# .env.test
DATABASE_URL="postgresql://user:pass@localhost:5432/app_test"
LOG_LEVEL="error"

# .env.production (via secrets management)
DATABASE_URL="${DATABASE_URL}"
REDIS_URL="${REDIS_URL}"
JWT_SECRET="${JWT_SECRET}"
```

**Environment validation:**

```typescript
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().optional(),
  JWT_SECRET: z.string().min(32),
  PORT: z.coerce.number().default(3000),
});

export const env = envSchema.parse(process.env);
```

---

## Git Workflows

### Trunk-Based Development

```
main (protected)
  │
  ├── feature/user-auth (short-lived, 1-2 days max)
  │   └── squash merge → main
  │
  ├── feature/payment-flow
  │   └── squash merge → main
  │
  └── release/v1.2.0 (cut from main for hotfixes)
```

**Branch naming:**
- `feature/description` - New features
- `fix/description` - Bug fixes
- `chore/description` - Maintenance tasks
- `release/vX.Y.Z` - Release branches

### Commit Standards

**Conventional Commits:**

```
<type>(<scope>): <description>

[optional body]

[optional footer(s)]
```

**Types:**
- `feat`: New feature
- `fix`: Bug fix
- `docs`: Documentation
- `style`: Formatting
- `refactor`: Code restructuring
- `test`: Adding tests
- `chore`: Maintenance

**Examples:**

```bash
feat(auth): add password reset flow

Implement password reset with email verification.
Tokens expire after 1 hour.

Closes #123

---

fix(api): handle null response in user endpoint

The API was returning 500 when user profile was incomplete.
Now returns partial data with null fields.

---

chore(deps): update Next.js to 14.1.0

Breaking changes addressed:
- Updated Image component usage
- Migrated to new metadata API
```

### Pre-commit Hooks

```json
// package.json
{
  "scripts": {
    "prepare": "husky install"
  },
  "lint-staged": {
    "*.{ts,tsx}": ["eslint --fix", "prettier --write"],
    "*.{json,md}": ["prettier --write"]
  }
}
```

```bash
# .husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx lint-staged

# .husky/commit-msg
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx commitlint --edit $1
```

---

## CI/CD Pipelines

### GitHub Actions

```yaml
# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - run: npm ci
      - run: npm run lint
      - run: npm run type-check

  test:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_USER: test
          POSTGRES_PASSWORD: test
          POSTGRES_DB: test
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - run: npm ci
      - run: npm run test:unit
      - run: npm run test:integration
        env:
          DATABASE_URL: postgresql://test:test@localhost:5432/test
      - uses: codecov/codecov-action@v3

  build:
    runs-on: ubuntu-latest
    needs: [lint, test]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - run: npm ci
      - run: npm run build
      - uses: actions/upload-artifact@v4
        with:
          name: build
          path: dist/

  deploy-preview:
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    needs: build
    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
        with:
          name: build
          path: dist/
      # Deploy to preview environment
      - name: Deploy Preview
        run: |
          # Deploy logic here
          echo "Deployed to preview-${{ github.event.pull_request.number }}"

  deploy-production:
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    needs: build
    environment: production
    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
        with:
          name: build
          path: dist/
      - name: Deploy Production
        run: |
          # Production deployment
          echo "Deployed to production"
```

### Database Migrations in CI

```yaml
# Part of deploy job
- name: Run Migrations
  run: |
    npx prisma migrate deploy
  env:
    DATABASE_URL: ${{ secrets.DATABASE_URL }}

- name: Verify Migration
  run: |
    npx prisma migrate status
```

---

## Testing Strategies

### Testing Pyramid

```
         /\
        /  \        E2E Tests (10%)
       /    \       - Critical user journeys
      /──────\
     /        \     Integration Tests (20%)
    /          \    - API endpoints
   /────────────\   - Database operations
  /              \
 /                \ Unit Tests (70%)
/──────────────────\ - Components, hooks, utilities
```

### Unit Testing

```typescript
// Component test with React Testing Library
import { render, screen, fireEvent } from "@testing-library/react";
import { UserForm } from "./UserForm";

describe("UserForm", () => {
  it("submits form with valid data", async () => {
    const onSubmit = vi.fn();
    render(<UserForm onSubmit={onSubmit} />);

    fireEvent.change(screen.getByLabelText(/email/i), {
      target: { value: "test@example.com" },
    });
    fireEvent.change(screen.getByLabelText(/name/i), {
      target: { value: "John Doe" },
    });
    fireEvent.click(screen.getByRole("button", { name: /submit/i }));

    await waitFor(() => {
      expect(onSubmit).toHaveBeenCalledWith({
        email: "test@example.com",
        name: "John Doe",
      });
    });
  });

  it("shows validation error for invalid email", async () => {
    render(<UserForm onSubmit={vi.fn()} />);

    fireEvent.change(screen.getByLabelText(/email/i), {
      target: { value: "invalid" },
    });
    fireEvent.click(screen.getByRole("button", { name: /submit/i }));

    expect(await screen.findByText(/invalid email/i)).toBeInTheDocument();
  });
});
```

### Integration Testing

```typescript
// API integration test
import { createTestClient } from "./test-utils";
import { db } from "@/lib/db";

describe("POST /api/users", () => {
  beforeEach(async () => {
    await db.user.deleteMany();
  });

  it("creates user with valid data", async () => {
    const client = createTestClient();

    const response = await client.post("/api/users", {
      email: "new@example.com",
      name: "New User",
    });

    expect(response.status).toBe(201);
    expect(response.data.user.email).toBe("new@example.com");

    // Verify in database
    const user = await db.user.findUnique({
      where: { email: "new@example.com" },
    });
    expect(user).toBeTruthy();
  });

  it("returns 409 for duplicate email", async () => {
    await db.user.create({
      data: { email: "existing@example.com", name: "Existing" },
    });

    const client = createTestClient();

    const response = await client.post("/api/users", {
      email: "existing@example.com",
      name: "Duplicate",
    });

    expect(response.status).toBe(409);
    expect(response.data.error.code).toBe("EMAIL_EXISTS");
  });
});
```

### E2E Testing with Playwright

```typescript
// e2e/auth.spec.ts
import { test, expect } from "@playwright/test";

test.describe("Authentication", () => {
  test("user can log in and access dashboard", async ({ page }) => {
    await page.goto("/login");

    await page.fill('[name="email"]', "user@example.com");
    await page.fill('[name="password"]', "password123");
    await page.click('button[type="submit"]');

    await expect(page).toHaveURL("/dashboard");
    await expect(page.locator("h1")).toHaveText("Welcome back");
  });

  test("shows error for invalid credentials", async ({ page }) => {
    await page.goto("/login");

    await page.fill('[name="email"]', "wrong@example.com");
    await page.fill('[name="password"]', "wrongpassword");
    await page.click('button[type="submit"]');

    await expect(page.locator('[role="alert"]')).toHaveText(
      "Invalid email or password"
    );
  });
});
```

---

## Code Review Process

### PR Template

```markdown
## Summary
<!-- Brief description of changes -->

## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update

## Changes Made
<!-- List specific changes -->

## Testing
- [ ] Unit tests added/updated
- [ ] Integration tests added/updated
- [ ] Manual testing completed

## Screenshots
<!-- If applicable -->

## Checklist
- [ ] Code follows style guidelines
- [ ] Self-review completed
- [ ] Documentation updated
- [ ] No new warnings
```

### Review Checklist

**Functionality:**
- Does the code do what it's supposed to?
- Are edge cases handled?
- Is error handling appropriate?

**Code Quality:**
- Is the code readable and maintainable?
- Are there any code smells?
- Is there unnecessary duplication?

**Performance:**
- Are there N+1 queries?
- Is caching used appropriately?
- Are there memory leaks?

**Security:**
- Is user input validated?
- Are there injection vulnerabilities?
- Is sensitive data protected?

---

## Deployment Strategies

### Blue-Green Deployment

```
                 Load Balancer
                      │
         ┌────────────┴────────────┐
         │                         │
    ┌────┴────┐              ┌─────┴────┐
    │  Blue   │              │  Green   │
    │ (Live)  │              │  (Idle)  │
    └─────────┘              └──────────┘

1. Deploy new version to Green
2. Run smoke tests on Green
3. Switch traffic to Green
4. Blue becomes idle (rollback target)
```

### Canary Deployment

```
                 Load Balancer
                      │
         ┌────────────┴────────────┐
         │                         │
         │ 95%                5%   │
         ▼                         ▼
    ┌─────────┐              ┌──────────┐
    │ Stable  │              │  Canary  │
    │ v1.0.0  │              │  v1.1.0  │
    └─────────┘              └──────────┘

1. Deploy canary with small traffic %
2. Monitor error rates, latency
3. Gradually increase traffic
4. Full rollout or rollback
```

### Feature Flags

```typescript
// Feature flag service
const flags = {
  newCheckoutFlow: {
    enabled: true,
    rolloutPercentage: 25,
    allowedUsers: ["beta-testers"],
  },
};

function isFeatureEnabled(flag: string, userId: string): boolean {
  const config = flags[flag];
  if (!config?.enabled) return false;

  // Check allowed users
  if (config.allowedUsers?.includes(userId)) return true;

  // Check rollout percentage
  const hash = hashUserId(userId);
  return hash < config.rolloutPercentage;
}

// Usage
if (isFeatureEnabled("newCheckoutFlow", user.id)) {
  return <NewCheckout />;
}
return <LegacyCheckout />;
```

---

## Monitoring and Observability

### Structured Logging

```typescript
import pino from "pino";

const logger = pino({
  level: process.env.LOG_LEVEL || "info",
  formatters: {
    level: (label) => ({ level: label }),
  },
});

// Request logging middleware
app.use((req, res, next) => {
  const start = Date.now();
  const requestId = req.headers["x-request-id"] || crypto.randomUUID();

  res.on("finish", () => {
    logger.info({
      type: "request",
      requestId,
      method: req.method,
      path: req.path,
      statusCode: res.statusCode,
      duration: Date.now() - start,
      userAgent: req.headers["user-agent"],
    });
  });

  next();
});

// Application logging
logger.info({ userId: user.id, action: "login" }, "User logged in");
logger.error({ err, orderId }, "Failed to process order");
```

### Metrics Collection

```typescript
import { Counter, Histogram } from "prom-client";

const httpRequestsTotal = new Counter({
  name: "http_requests_total",
  help: "Total HTTP requests",
  labelNames: ["method", "path", "status"],
});

const httpRequestDuration = new Histogram({
  name: "http_request_duration_seconds",
  help: "HTTP request duration",
  labelNames: ["method", "path"],
  buckets: [0.1, 0.3, 0.5, 1, 3, 5, 10],
});

// Middleware
app.use((req, res, next) => {
  const end = httpRequestDuration.startTimer({
    method: req.method,
    path: req.route?.path || req.path,
  });

  res.on("finish", () => {
    httpRequestsTotal.inc({
      method: req.method,
      path: req.route?.path || req.path,
      status: res.statusCode,
    });
    end();
  });

  next();
});
```

### Health Checks

```typescript
app.get("/health", async (req, res) => {
  const checks = {
    database: await checkDatabase(),
    redis: await checkRedis(),
    memory: checkMemory(),
  };

  const healthy = Object.values(checks).every((c) => c.status === "healthy");

  res.status(healthy ? 200 : 503).json({
    status: healthy ? "healthy" : "unhealthy",
    checks,
    timestamp: new Date().toISOString(),
  });
});

async function checkDatabase() {
  try {
    await db.$queryRaw`SELECT 1`;
    return { status: "healthy" };
  } catch (error) {
    return { status: "unhealthy", error: error.message };
  }
}

function checkMemory() {
  const used = process.memoryUsage();
  const heapUsedMB = Math.round(used.heapUsed / 1024 / 1024);
  const heapTotalMB = Math.round(used.heapTotal / 1024 / 1024);

  return {
    status: heapUsedMB < heapTotalMB * 0.9 ? "healthy" : "warning",
    heapUsedMB,
    heapTotalMB,
  };
}
```

---

## Quick Reference

### Daily Workflow

```bash
# 1. Start work
git checkout main && git pull
git checkout -b feature/my-feature

# 2. Develop with hot reload
docker-compose up -d
npm run dev

# 3. Test changes
npm run test
npm run lint

# 4. Commit
git add -A
git commit -m "feat(scope): description"

# 5. Push and create PR
git push -u origin feature/my-feature
gh pr create
```

### Release Workflow

```bash
# 1. Ensure main is stable
git checkout main
npm run test:all

# 2. Create release
npm version minor  # or major/patch
git push --follow-tags

# 3. Verify deployment
# CI/CD deploys automatically
# Monitor dashboards
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.