Agent Skills › CloudAI-X/opencode-workflow

CloudAI-X/opencode-workflow

GitHub

提供系统化的代码库分析框架,通过五层发现流程(表面扫描、依赖映射、架构识别、流程追踪、质量评估)帮助开发者快速理解新项目的结构、模式和依赖关系。

7 skills 230

Install All Skills

npx skills add CloudAI-X/opencode-workflow --all -g -y
More Options

List skills in collection

npx skills add CloudAI-X/opencode-workflow --list

Skills in Collection (7)

提供系统化的代码库分析框架,通过五层发现流程(表面扫描、依赖映射、架构识别、流程追踪、质量评估)帮助开发者快速理解新项目的结构、模式和依赖关系。
入职新项目或熟悉新代码库 在修改代码前理解系统结构 调查功能实现方式 映射模块间依赖关系 识别架构模式
skills/analyzing-projects/SKILL.md
npx skills add CloudAI-X/opencode-workflow --skill analyzing-projects -g -y
SKILL.md
Frontmatter
{
    "name": "analyzing-projects",
    "license": "MIT",
    "metadata": {
        "audience": "developers",
        "category": "exploration"
    },
    "description": "Guides systematic project analysis, codebase exploration, and architecture pattern recognition. Use when understanding new codebases, onboarding to projects, or investigating system structure.",
    "compatibility": "opencode"
}

Analyzing Projects

Systematic approaches to understanding codebases, identifying patterns, and mapping system architecture.

When to Use This Skill

  • Onboarding to a new codebase
  • Understanding unfamiliar code before making changes
  • Investigating how features are implemented
  • Mapping dependencies between modules
  • Identifying architectural patterns in use

Core Analysis Framework

The 5-Layer Discovery Process

Layer 1: Surface Scan
  └─ Entry points, config files, directory structure

Layer 2: Dependency Mapping
  └─ Package managers, imports, module relationships

Layer 3: Architecture Recognition
  └─ Patterns (MVC, hexagonal, microservices)

Layer 4: Flow Tracing
  └─ Request paths, data flow, state management

Layer 5: Quality Assessment
  └─ Test coverage, code health, technical debt

Phase 1: Surface Scan

Entry Point Discovery

Start by identifying how the application launches:

  1. Look for standard entry files:

    • main.*, index.*, app.*, server.*
    • cmd/ directory (Go)
    • src/main/ (Java)
    • bin/ scripts
  2. Check configuration files:

    • package.json (scripts.start, main)
    • Makefile, Taskfile
    • Docker/Compose files
    • CI/CD configs (.github/workflows/)
  3. Map directory structure:

    Quick heuristics:
    ├── src/           → Source code
    ├── lib/           → Internal libraries
    ├── pkg/           → Public packages (Go)
    ├── internal/      → Private packages (Go)
    ├── tests/         → Test files
    ├── docs/          → Documentation
    ├── scripts/       → Build/deploy scripts
    └── config/        → Configuration
    

Initial Questions to Answer

  • What language(s) and framework(s)?
  • What's the build system?
  • How is the app deployed?
  • Where are the main entry points?

Phase 2: Dependency Mapping

Package Manager Analysis

File Ecosystem Key Sections
package.json Node.js dependencies, devDependencies
requirements.txt / pyproject.toml Python direct dependencies
go.mod Go require blocks
Cargo.toml Rust dependencies
pom.xml / build.gradle Java dependencies

Internal Module Relationships

  1. Trace imports from entry points

  2. Build a mental model of layers:

    Presentation Layer (routes, controllers, views)
          ↓
    Application Layer (services, use cases)
          ↓
    Domain Layer (entities, business logic)
          ↓
    Infrastructure Layer (database, external APIs)
    
  3. Identify shared utilities imported across modules


Phase 3: Architecture Recognition

Common Patterns to Identify

Pattern Indicators Typical Structure
MVC controllers/, models/, views/ Clear separation of concerns
Hexagonal ports/, adapters/, domain/ Dependency inversion
Microservices services/, docker-compose Independent deployable units
Monolith Single large app, shared DB Everything in one deployment
Serverless functions/, handlers/ Event-driven, stateless

Architecture Questions

  • How are concerns separated?
  • Where does business logic live?
  • How are external dependencies abstracted?
  • What's the data access pattern?

Phase 4: Flow Tracing

Request Path Analysis

For web applications, trace a request end-to-end:

HTTP Request
    ↓
Router/Routes (maps URL → handler)
    ↓
Middleware (auth, logging, validation)
    ↓
Controller/Handler (orchestrates)
    ↓
Service/Use Case (business logic)
    ↓
Repository/DAO (data access)
    ↓
Database/External API

State Management Analysis

For frontend applications:

  • Where is state stored? (Redux, Zustand, Context)
  • How does data flow? (unidirectional, bidirectional)
  • What triggers re-renders?

Phase 5: Quality Assessment

Code Health Indicators

Indicator Good Sign Warning Sign
Test coverage >70% coverage No tests, or tests ignored
Dependencies Recent versions Major versions behind
Documentation README updated Stale or missing docs
Build time Under 2 minutes Over 10 minutes
Error handling Consistent patterns Swallowed exceptions

Technical Debt Markers

  • TODO/FIXME comments
  • Disabled tests
  • Large functions (>50 lines)
  • Deep nesting (>4 levels)
  • Duplicated code blocks
  • Hardcoded values

Analysis Strategies by Goal

Goal: Make a Bug Fix

  1. Find where the bug manifests
  2. Trace back to the root cause
  3. Understand the affected area only
  4. Check for related tests

Goal: Add a New Feature

  1. Find similar existing features
  2. Understand the patterns they use
  3. Map the modules that need changes
  4. Identify integration points

Goal: Full Codebase Understanding

  1. Complete all 5 phases
  2. Document architecture decisions
  3. Create a mental map of key flows
  4. Identify ownership areas

Parallel Analysis Pattern

When exploring a large codebase, parallelize by module:

Spawn subagents for each major area:
├─ Subagent 1: Analyze src/auth (authentication module)
├─ Subagent 2: Analyze src/api (API layer)
├─ Subagent 3: Analyze src/db (data layer)
├─ Subagent 4: Analyze src/ui (frontend)
└─ Subagent 5: Analyze tests/ (test patterns)

Synthesize findings into unified architecture view.

Output Templates

Quick Architecture Summary

## Project Overview
- **Language**: [Primary language]
- **Framework**: [Main framework]
- **Architecture**: [Pattern identified]
- **Entry Point**: [Main file]

## Key Modules
| Module | Responsibility | Key Files |
|--------|----------------|-----------|
| [Name] | [What it does] | [Files]   |

## Data Flow
[Request lifecycle diagram]

## Notable Patterns
- [Pattern 1]: [Where/how used]
- [Pattern 2]: [Where/how used]

Onboarding Checklist

## Getting Started
- [ ] Clone and install dependencies
- [ ] Run the app locally
- [ ] Run the test suite
- [ ] Trace one request end-to-end
- [ ] Find where [core feature] is implemented

Anti-Patterns to Avoid

  1. Analysis Paralysis - Don't try to understand everything before starting
  2. Ignoring Tests - Tests often document expected behavior
  3. Skipping Config - Configuration reveals deployment context
  4. Surface-Only - Don't stop at directory structure
  5. Assuming Patterns - Verify patterns, don't assume from naming

Quick Reference

SURFACE SCAN:
  entry points → config files → directory structure

DEPENDENCY MAP:
  package manager → import tracing → layer identification

ARCHITECTURE:
  pattern recognition → separation of concerns → abstractions

FLOW TRACING:
  request path → data flow → state management

QUALITY CHECK:
  test coverage → code health → technical debt
提供REST和GraphQL API设计指南,涵盖端点模式、请求响应Schema、版本控制及最佳实践。适用于构建API、设计端点或审查API契约的场景。
设计新的API端点 审查API契约 规划API版本策略 定义请求/响应Schema 构建GraphQL Schema 文档化API
skills/designing-apis/SKILL.md
npx skills add CloudAI-X/opencode-workflow --skill designing-apis -g -y
SKILL.md
Frontmatter
{
    "name": "designing-apis",
    "license": "MIT",
    "metadata": {
        "audience": "developers",
        "category": "design"
    },
    "description": "Guides REST and GraphQL API design, endpoint patterns, request\/response schemas, versioning, and API best practices. Use when building APIs, designing endpoints, or reviewing API contracts.",
    "compatibility": "opencode"
}

Designing APIs

Principles and patterns for designing clean, consistent, and maintainable APIs.

When to Use This Skill

  • Designing new API endpoints
  • Reviewing API contracts
  • Planning API versioning strategies
  • Defining request/response schemas
  • Building GraphQL schemas
  • Documenting APIs

REST API Design Principles

Resource-Oriented Design

APIs should be organized around resources, not actions:

GOOD (Resource-oriented):
GET    /users           → List users
GET    /users/123       → Get user 123
POST   /users           → Create user
PUT    /users/123       → Update user 123
DELETE /users/123       → Delete user 123

BAD (Action-oriented):
POST   /getUsers
POST   /createUser
POST   /updateUser
POST   /deleteUser

HTTP Method Semantics

Method Purpose Idempotent Safe Request Body
GET Retrieve resource(s) Yes Yes No
POST Create resource No No Yes
PUT Replace resource Yes No Yes
PATCH Partial update Yes No Yes
DELETE Remove resource Yes No Optional

URL Structure Patterns

Collection:     /users
Item:           /users/{id}
Nested:         /users/{id}/posts
Action:         /users/{id}/activate (POST only, for non-CRUD)
Filter:         /users?status=active&role=admin
Pagination:     /users?page=2&limit=20
Sort:           /users?sort=created_at&order=desc

Request Design

Path Parameters vs Query Parameters

Use Path Parameters Query Parameters
Resource identification /users/123 -
Required filters /orgs/456/users -
Optional filters - ?status=active
Pagination - ?page=2&limit=20
Sorting - ?sort=name&order=asc
Search - ?q=searchterm

Request Body Patterns

// POST /users - Create
{
  "email": "user@example.com",
  "name": "John Doe",
  "role": "admin"
}

// PATCH /users/123 - Partial update
{
  "name": "Jane Doe"
}

// Bulk operations - POST /users/bulk
{
  "operations": [
    { "action": "create", "data": { "email": "..." } },
    { "action": "update", "id": "123", "data": { "name": "..." } }
  ]
}

Response Design

Consistent Response Envelope

// Success response
{
  "data": { ... },
  "meta": {
    "timestamp": "2024-01-15T10:30:00Z",
    "requestId": "abc123"
  }
}

// Collection response with pagination
{
  "data": [ ... ],
  "meta": {
    "total": 100,
    "page": 2,
    "limit": 20,
    "hasMore": true
  }
}

// Error response
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid request data",
    "details": [
      { "field": "email", "message": "Invalid email format" }
    ]
  },
  "meta": {
    "timestamp": "2024-01-15T10:30:00Z",
    "requestId": "abc123"
  }
}

HTTP Status Code Guidelines

Range Category Common Codes
2xx Success 200 OK, 201 Created, 204 No Content
3xx Redirect 301 Moved, 304 Not Modified
4xx Client Error 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 422 Unprocessable
5xx Server Error 500 Internal, 502 Bad Gateway, 503 Unavailable

Status Code Decision Tree

Success?
├─ Yes
│  ├─ Returning data? → 200 OK
│  ├─ Created resource? → 201 Created
│  └─ No content? → 204 No Content
└─ No
   ├─ Client's fault?
   │  ├─ Bad syntax? → 400 Bad Request
   │  ├─ Not authenticated? → 401 Unauthorized
   │  ├─ Not authorized? → 403 Forbidden
   │  ├─ Not found? → 404 Not Found
   │  └─ Validation failed? → 422 Unprocessable Entity
   └─ Server's fault? → 500 Internal Server Error

API Versioning Strategies

URL Path Versioning (Recommended)

/api/v1/users
/api/v2/users

Pros: Explicit, easy to understand, easy to route Cons: URL changes between versions

Header Versioning

GET /api/users
Accept: application/vnd.myapi.v2+json

Pros: Clean URLs Cons: Hidden version, harder to test

Query Parameter Versioning

/api/users?version=2

Pros: Flexible, easy to test Cons: Can be forgotten, pollutes query string


GraphQL Design Patterns

Schema-First Design

type User {
  id: ID!
  email: String!
  name: String!
  posts: [Post!]!
  createdAt: DateTime!
}

type Post {
  id: ID!
  title: String!
  content: String!
  author: User!
  createdAt: DateTime!
}

type Query {
  user(id: ID!): User
  users(filter: UserFilter, page: PageInput): UserConnection!
}

type Mutation {
  createUser(input: CreateUserInput!): User!
  updateUser(id: ID!, input: UpdateUserInput!): User!
  deleteUser(id: ID!): Boolean!
}

Input Types Pattern

input CreateUserInput {
  email: String!
  name: String!
  role: Role = USER
}

input UpdateUserInput {
  email: String
  name: String
  role: Role
}

input UserFilter {
  status: UserStatus
  role: Role
  search: String
}

Pagination Patterns

# Cursor-based (recommended for large datasets)
type UserConnection {
  edges: [UserEdge!]!
  pageInfo: PageInfo!
}

type UserEdge {
  node: User!
  cursor: String!
}

type PageInfo {
  hasNextPage: Boolean!
  hasPreviousPage: Boolean!
  startCursor: String
  endCursor: String
}

# Offset-based (simpler, for smaller datasets)
type UserList {
  items: [User!]!
  total: Int!
  page: Int!
  limit: Int!
}

Authentication & Authorization

Authentication Patterns

Pattern Use Case Header
Bearer Token Standard API auth Authorization: Bearer <token>
API Key Server-to-server X-API-Key: <key>
Basic Auth Simple/legacy systems Authorization: Basic <base64>
OAuth 2.0 Third-party integration OAuth flow

Authorization Responses

Not authenticated → 401 Unauthorized
  (User identity unknown)

Not authorized → 403 Forbidden
  (User known, but lacks permission)

Error Handling Patterns

Standardized Error Format

{
  "error": {
    "code": "RESOURCE_NOT_FOUND",
    "message": "User with ID 123 not found",
    "target": "user",
    "details": [
      {
        "code": "INVALID_ID",
        "message": "The provided ID does not exist",
        "target": "id"
      }
    ],
    "innererror": {
      "trace": "abc123",
      "timestamp": "2024-01-15T10:30:00Z"
    }
  }
}

Common Error Codes

Code HTTP Status When
VALIDATION_ERROR 400/422 Request data invalid
UNAUTHORIZED 401 Auth required
FORBIDDEN 403 Insufficient permissions
NOT_FOUND 404 Resource doesn't exist
CONFLICT 409 State conflict (duplicate)
RATE_LIMITED 429 Too many requests
INTERNAL_ERROR 500 Server failure

API Documentation

OpenAPI/Swagger Structure

openapi: 3.0.3
info:
  title: My API
  version: 1.0.0

paths:
  /users:
    get:
      summary: List users
      parameters:
        - name: status
          in: query
          schema:
            type: string
            enum: [active, inactive]
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserList'

components:
  schemas:
    User:
      type: object
      required: [id, email]
      properties:
        id:
          type: string
        email:
          type: string
          format: email

Anti-Patterns to Avoid

  1. Verbs in URLs - Use /users not /getUsers
  2. Ignoring HTTP Methods - Use proper methods, not POST for everything
  3. Inconsistent Naming - Pick snake_case or camelCase, stick with it
  4. Leaking Implementation - Don't expose internal IDs or DB structure
  5. Missing Pagination - Always paginate collections
  6. Ignoring Idempotency - PUT/DELETE must be idempotent
  7. No Versioning - Plan for API evolution from day one

Quick Reference

RESOURCE DESIGN:
  /resources           → Collection
  /resources/{id}      → Item
  /resources/{id}/sub  → Nested

HTTP METHODS:
  GET     → Read (safe, idempotent)
  POST    → Create (not idempotent)
  PUT     → Replace (idempotent)
  PATCH   → Update (idempotent)
  DELETE  → Remove (idempotent)

STATUS CODES:
  200 OK, 201 Created, 204 No Content
  400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found
  500 Internal Server Error

VERSIONING:
  /api/v1/resources (recommended)

PAGINATION:
  ?page=2&limit=20 (offset)
  ?cursor=abc123&limit=20 (cursor)
指导软件架构决策、设计模式及系统原则,适用于新系统设计、模式选择、技术决策、架构审查、扩展规划及遗留系统重构。
设计新系统或功能 选择架构模式 做出技术决策 审查系统设计 规划可扩展性 重构遗留系统
skills/designing-architecture/SKILL.md
npx skills add CloudAI-X/opencode-workflow --skill designing-architecture -g -y
SKILL.md
Frontmatter
{
    "name": "designing-architecture",
    "license": "MIT",
    "metadata": {
        "audience": "developers",
        "category": "design"
    },
    "description": "Guides software architecture decisions, design patterns, and system design principles. Use when designing systems, choosing patterns, or making architectural decisions.",
    "compatibility": "opencode"
}

Designing Architecture

Principles and patterns for designing maintainable, scalable, and robust software systems.

When to Use This Skill

  • Designing new systems or features
  • Choosing between architectural patterns
  • Making technology decisions
  • Reviewing system design
  • Planning for scalability
  • Refactoring legacy systems

Core Architecture Principles

SOLID Principles

Principle Summary Violation Sign
Single Responsibility One reason to change Class does too many things
Open/Closed Open for extension, closed for modification Modifying existing code for new features
Liskov Substitution Subtypes replaceable for base types Overrides break parent behavior
Interface Segregation Small, focused interfaces Classes implement unused methods
Dependency Inversion Depend on abstractions High-level modules depend on low-level

The Dependency Rule

Outer layers depend on inner layers, NEVER the reverse.

┌─────────────────────────────────────┐
│     Frameworks & Drivers           │  ← Database, Web, UI
├─────────────────────────────────────┤
│     Interface Adapters             │  ← Controllers, Presenters, Gateways
├─────────────────────────────────────┤
│     Application Business Rules     │  ← Use Cases
├─────────────────────────────────────┤
│     Enterprise Business Rules      │  ← Entities
└─────────────────────────────────────┘

Dependencies point INWARD only.

Architectural Patterns

Layered Architecture

┌─────────────────────────────────────┐
│     Presentation Layer             │  ← UI, API Controllers
├─────────────────────────────────────┤
│     Application Layer              │  ← Use Cases, Services
├─────────────────────────────────────┤
│     Domain Layer                   │  ← Business Logic, Entities
├─────────────────────────────────────┤
│     Infrastructure Layer           │  ← Database, External APIs
└─────────────────────────────────────┘

Use when: Traditional applications, clear separation needed Avoid when: High-performance needs, event-driven systems

Hexagonal Architecture (Ports & Adapters)

           ┌───────────────┐
           │   Primary     │
           │   Adapters    │  ← REST API, CLI, GraphQL
           └───────┬───────┘
                   │
        ┌──────────▼──────────┐
        │                     │
        │   ┌───────────┐     │
        │   │   Core    │     │
Primary │   │  Domain   │     │ Secondary
Ports   │   │  Logic    │     │ Ports
        │   └───────────┘     │
        │                     │
        └──────────┬──────────┘
                   │
           ┌───────▼───────┐
           │   Secondary   │
           │   Adapters    │  ← Database, Message Queue, External API
           └───────────────┘

Use when: Testability is critical, multiple interfaces needed Avoid when: Simple CRUD applications

Microservices Architecture

┌─────────┐  ┌─────────┐  ┌─────────┐
│ Service │  │ Service │  │ Service │
│    A    │  │    B    │  │    C    │
└────┬────┘  └────┬────┘  └────┬────┘
     │            │            │
     └────────────┴────────────┘
                  │
           ┌──────▼──────┐
           │   Message   │
           │    Bus      │
           └─────────────┘

Use when: Independent scaling, team autonomy, polyglot needs Avoid when: Small teams, simple domains, tight coupling required

Event-Driven Architecture

Event Source → Event Bus → Event Handlers
     │              │              │
     ▼              ▼              ▼
  Produces    Routes Events    Consumes
  Events      (Kafka, RabbitMQ)  Events

Use when: Async processing, decoupling, audit trails Avoid when: Immediate consistency required, simple workflows


Design Patterns

Creational Patterns

Pattern Purpose When to Use
Factory Create objects without specifying class Object creation logic is complex
Builder Construct complex objects step-by-step Many optional parameters
Singleton Single instance globally Shared resource (use sparingly)
Dependency Injection Inject dependencies externally Testability, loose coupling

Structural Patterns

Pattern Purpose When to Use
Adapter Convert interface to another Integrating incompatible systems
Decorator Add behavior dynamically Extending functionality without inheritance
Facade Simplified interface to complex system Hiding complexity
Repository Abstract data access Separating domain from persistence

Behavioral Patterns

Pattern Purpose When to Use
Strategy Interchangeable algorithms Multiple ways to do something
Observer Notify dependents of changes Event systems, reactive updates
Command Encapsulate actions as objects Undo/redo, queuing, logging
Chain of Responsibility Pass request along handlers Middleware, validation chains

Domain-Driven Design Concepts

Strategic Design

Concept Definition Example
Bounded Context Explicit boundary for a domain model Order context, Shipping context
Ubiquitous Language Shared vocabulary between devs and domain experts "Order", "Line Item", "Fulfillment"
Context Map How bounded contexts relate Customer shared between Sales and Support

Tactical Patterns

Pattern Purpose Example
Entity Object with identity User, Order
Value Object Object without identity Money, Address
Aggregate Cluster of entities with root Order + LineItems
Domain Event Something that happened OrderPlaced, PaymentReceived
Repository Collection-like access to aggregates OrderRepository
Domain Service Logic that doesn't fit entities PricingService

System Design Considerations

Scalability Patterns

Pattern Description Trade-off
Horizontal Scaling Add more instances Statelessness required
Vertical Scaling Bigger machines Hardware limits
Caching Store computed results Cache invalidation
Database Sharding Split data across DBs Query complexity
Read Replicas Separate read/write Eventual consistency
CDN Edge content delivery Static content only

Resilience Patterns

Pattern Purpose Implementation
Circuit Breaker Prevent cascade failures Fail fast when downstream is down
Retry with Backoff Handle transient failures Exponential delay between retries
Bulkhead Isolate failures Separate thread pools per dependency
Timeout Bound waiting time Max wait for responses
Fallback Graceful degradation Default behavior when service unavailable

Data Consistency Patterns

Pattern Consistency Use When
ACID Transactions Strong Financial data, critical operations
Saga Eventual Distributed transactions
Event Sourcing Eventual Audit trails, complex state
CQRS Eventual Different read/write models

Technology Decision Framework

When to Use a Database

Need Recommended Avoid
Relational data, ACID PostgreSQL, MySQL MongoDB
Document storage, flexible schema MongoDB, DynamoDB Relational
Key-value, high speed Redis, Memcached Relational
Time series InfluxDB, TimescaleDB Generic SQL
Graph relationships Neo4j, Neptune Relational (for complex)
Search Elasticsearch, Meilisearch Full table scans

When to Use Message Queues

Need Pattern
Async processing Queue (SQS, RabbitMQ)
Event broadcasting Pub/Sub (SNS, Kafka)
Task scheduling Delayed queues
Load leveling Queue with workers
Event sourcing Log-based (Kafka)

Architecture Decision Records (ADR)

Template

# ADR-001: [Title]

## Status
[Proposed | Accepted | Deprecated | Superseded by ADR-XXX]

## Context
[Why is this decision needed?]

## Decision
[What is the decision?]

## Consequences
### Positive
- [Benefit 1]
- [Benefit 2]

### Negative
- [Trade-off 1]
- [Trade-off 2]

## Alternatives Considered
1. [Alternative 1] - [Why rejected]
2. [Alternative 2] - [Why rejected]

Anti-Patterns to Avoid

  1. Big Ball of Mud - No clear structure, everything depends on everything
  2. Golden Hammer - Using one pattern for all problems
  3. Premature Optimization - Designing for scale before proving need
  4. Analysis Paralysis - Over-designing, never shipping
  5. Distributed Monolith - Microservices with tight coupling
  6. Anemic Domain Model - Entities with only getters/setters
  7. God Object - One class that does everything
  8. Leaky Abstraction - Implementation details leak through interfaces

Decision Checklist

Before finalizing an architecture decision, verify:

  • Does it solve the actual problem?
  • Is it the simplest solution that works?
  • Can the team maintain it?
  • Does it align with existing patterns?
  • Is it testable?
  • Can it evolve as requirements change?
  • Are the trade-offs acceptable?
  • Is the decision documented?

Quick Reference

SOLID:
  S - Single Responsibility
  O - Open/Closed
  L - Liskov Substitution
  I - Interface Segregation
  D - Dependency Inversion

PATTERNS:
  Layered     → Simple, clear separation
  Hexagonal   → Testable, adaptable
  Microservices → Scalable, independent
  Event-Driven  → Decoupled, async

DDD BUILDING BLOCKS:
  Entity, Value Object, Aggregate
  Repository, Domain Event, Domain Service

SCALABILITY:
  Horizontal scaling, Caching, Sharding, CDN

RESILIENCE:
  Circuit Breaker, Retry, Bulkhead, Timeout
指导测试策略设计、TDD/BDD实践、覆盖率规划及最佳实践。适用于构建测试套件、优化覆盖率、选择测试方法(如金字塔模型)及调试不稳定测试。
规划新功能测试覆盖率 在TDD和BDD间选择测试方法 设计集成或E2E测试 改进现有测试套件 搭建测试基础设施 调试不稳定测试
skills/designing-tests/SKILL.md
npx skills add CloudAI-X/opencode-workflow --skill designing-tests -g -y
SKILL.md
Frontmatter
{
    "name": "designing-tests",
    "license": "MIT",
    "metadata": {
        "audience": "developers",
        "category": "quality"
    },
    "description": "Guides test strategy, TDD\/BDD approaches, test coverage planning, and testing best practices. Use when designing test suites, improving coverage, or choosing testing approaches.",
    "compatibility": "opencode"
}

Designing Tests

Strategies and patterns for designing effective, maintainable test suites.

When to Use This Skill

  • Planning test coverage for new features
  • Choosing between testing approaches (TDD, BDD)
  • Designing integration or E2E tests
  • Improving existing test suites
  • Setting up testing infrastructure
  • Debugging flaky tests

The Testing Pyramid

                 ┌─────────┐
                 │   E2E   │  ← Few, slow, expensive
                 │  Tests  │     (Selenium, Playwright)
                 ├─────────┤
                 │         │
              ┌──┤ Integr- │  ← Some, medium speed
              │  │  ation  │     (API tests, DB tests)
              │  │  Tests  │
              │  ├─────────┤
              │  │         │
              │  │  Unit   │  ← Many, fast, cheap
              │  │  Tests  │     (Pure functions, isolated)
              └──┴─────────┘
Level Speed Scope Quantity Purpose
Unit ~ms Single function/class Many (70-80%) Logic correctness
Integration ~s Multiple components Some (15-20%) Component interaction
E2E ~10s+ Full system Few (5-10%) User flows work

Test-Driven Development (TDD)

The Red-Green-Refactor Cycle

     ┌─────────────────────────────────┐
     │                                 │
     ▼                                 │
┌─────────┐    ┌─────────┐    ┌────────┴──┐
│   RED   │───▶│  GREEN  │───▶│ REFACTOR  │
│  Write  │    │  Make   │    │  Clean    │
│ failing │    │   it    │    │   up      │
│  test   │    │  pass   │    │  code     │
└─────────┘    └─────────┘    └───────────┘

TDD Best Practices

  1. Write the test first - Don't write production code without a failing test
  2. Write the minimal test - One behavior per test
  3. Write the minimal code - Just enough to pass
  4. Refactor ruthlessly - Clean up after green
  5. Run tests frequently - After every small change

TDD Example Flow

# Step 1: RED - Write failing test
def test_calculate_total_with_discount():
    order = Order(items=[Item(price=100)])
    order.apply_discount(10)  # 10%
    assert order.total() == 90

# Step 2: GREEN - Minimal implementation
class Order:
    def __init__(self, items):
        self.items = items
        self.discount = 0

    def apply_discount(self, percent):
        self.discount = percent

    def total(self):
        subtotal = sum(i.price for i in self.items)
        return subtotal * (100 - self.discount) / 100

# Step 3: REFACTOR - Clean up (if needed)

Behavior-Driven Development (BDD)

Gherkin Syntax

Feature: Shopping Cart
  As a customer
  I want to add items to my cart
  So that I can purchase them later

  Scenario: Add item to empty cart
    Given I have an empty cart
    When I add a product "Widget" priced at $10
    Then my cart should contain 1 item
    And my cart total should be $10

  Scenario: Apply discount code
    Given I have a cart with total $100
    When I apply discount code "SAVE10"
    Then my cart total should be $90

BDD Benefits

  • Tests as documentation
  • Shared language with stakeholders
  • Focus on behavior, not implementation
  • Easy to understand test intent

Test Design Patterns

Arrange-Act-Assert (AAA)

def test_user_registration():
    # Arrange - Set up preconditions
    user_data = {"email": "test@example.com", "password": "secure123"}
    user_service = UserService(mock_repository)

    # Act - Perform the action
    result = user_service.register(user_data)

    # Assert - Verify the outcome
    assert result.success is True
    assert result.user.email == "test@example.com"

Given-When-Then (BDD style)

def test_order_cancellation():
    # Given - a confirmed order
    order = create_confirmed_order()

    # When - the customer cancels it
    order.cancel()

    # Then - the order is cancelled and refund initiated
    assert order.status == "cancelled"
    assert order.refund_initiated is True

Test Data Builders

class UserBuilder:
    def __init__(self):
        self.email = "default@test.com"
        self.name = "Test User"
        self.role = "user"

    def with_email(self, email):
        self.email = email
        return self

    def with_role(self, role):
        self.role = role
        return self

    def build(self):
        return User(email=self.email, name=self.name, role=self.role)

# Usage
admin = UserBuilder().with_role("admin").build()

Object Mother Pattern

class TestUsers:
    @staticmethod
    def admin():
        return User(email="admin@test.com", role="admin")

    @staticmethod
    def customer():
        return User(email="customer@test.com", role="customer")

    @staticmethod
    def guest():
        return User(email=None, role="guest")

Mocking Strategies

When to Mock

Mock Don't Mock
External APIs Pure business logic
Database (for unit tests) Simple value objects
File system Deterministic functions
Time/random Core domain entities
Third-party services Internal collaborators (usually)

Mock Types

Type Purpose Example
Stub Return canned responses mock.return_value = 42
Mock Verify interactions mock.assert_called_with(...)
Spy Track real calls Wraps real object, records calls
Fake Simplified implementation In-memory database

Mocking Example

# Using unittest.mock
from unittest.mock import Mock, patch

def test_send_email_on_registration():
    # Arrange
    mock_email_service = Mock()
    user_service = UserService(email_service=mock_email_service)

    # Act
    user_service.register({"email": "test@example.com"})

    # Assert
    mock_email_service.send_welcome_email.assert_called_once_with("test@example.com")

# Using patch decorator
@patch("app.services.EmailService")
def test_with_patch(mock_email_class):
    mock_email_class.return_value.send.return_value = True
    # Test code...

Integration Test Patterns

Database Tests

import pytest
from testcontainers.postgres import PostgresContainer

@pytest.fixture(scope="session")
def database():
    with PostgresContainer("postgres:15") as postgres:
        yield postgres.get_connection_url()

def test_user_persistence(database):
    repo = UserRepository(database)
    user = User(email="test@example.com")

    repo.save(user)
    retrieved = repo.find_by_email("test@example.com")

    assert retrieved.email == user.email

API Tests

def test_create_user_endpoint(client):
    response = client.post("/api/users", json={
        "email": "new@example.com",
        "password": "secure123"
    })

    assert response.status_code == 201
    assert response.json["email"] == "new@example.com"
    assert "id" in response.json

E2E Test Patterns

Page Object Model

class LoginPage:
    def __init__(self, page):
        self.page = page
        self.email_input = page.locator("#email")
        self.password_input = page.locator("#password")
        self.submit_button = page.locator("button[type=submit]")

    def login(self, email, password):
        self.email_input.fill(email)
        self.password_input.fill(password)
        self.submit_button.click()
        return DashboardPage(self.page)

# Usage
def test_successful_login(page):
    login_page = LoginPage(page)
    dashboard = login_page.login("user@example.com", "password")
    assert dashboard.welcome_message.is_visible()

E2E Best Practices

  1. Use stable selectors - data-testid, not CSS classes
  2. Wait for conditions - Not arbitrary sleeps
  3. Isolate test data - Each test gets fresh data
  4. Test critical paths - Happy paths, key user journeys
  5. Keep them fast - Parallelize, minimize scope

Test Coverage Strategy

What to Cover

Priority What Why
High Business logic Core value
High Edge cases Where bugs hide
High Error paths Graceful failures
Medium Integration points Contract validation
Low UI layout Brittle, low value
Low Third-party code Not your responsibility

Coverage Metrics

Metric Target Notes
Line coverage 70-80% Basic minimum
Branch coverage 60-70% Catches conditionals
Mutation score 50-70% Measures test quality

Meaningful Coverage

HIGH VALUE:
  ✓ Core business logic
  ✓ Data transformations
  ✓ Error handling
  ✓ Security-sensitive code

LOW VALUE:
  ✗ Getters/setters
  ✗ Constructor-only classes
  ✗ Framework boilerplate
  ✗ Configuration files

Handling Flaky Tests

Common Causes

Cause Solution
Timing issues Use explicit waits, not sleep
Shared state Isolate test data
External dependencies Mock or use containers
Race conditions Add synchronization
Date/time Mock time providers
Random data Seed random generators

Flaky Test Checklist

  • Is the test relying on timing?
  • Is there shared state between tests?
  • Is there an external dependency?
  • Is the order of execution assumed?
  • Is there non-deterministic data?

Test Organization

File Structure

tests/
├── unit/                    # Unit tests
│   ├── services/
│   │   └── test_user_service.py
│   └── models/
│       └── test_order.py
├── integration/             # Integration tests
│   ├── api/
│   │   └── test_user_endpoints.py
│   └── repositories/
│       └── test_user_repository.py
├── e2e/                     # End-to-end tests
│   └── test_checkout_flow.py
├── fixtures/                # Shared fixtures
│   └── factories.py
└── conftest.py              # Pytest configuration

Naming Conventions

# Pattern: test_[what]_[condition]_[expected]

def test_calculate_total_with_discount_returns_reduced_price():
    pass

def test_login_with_invalid_password_raises_auth_error():
    pass

def test_order_when_cancelled_sends_refund_notification():
    pass

Anti-Patterns to Avoid

  1. Testing implementation, not behavior - Tests break on refactor
  2. Large test methods - Hard to debug, unclear intent
  3. Excessive mocking - Tests don't reflect reality
  4. Shared mutable state - Tests affect each other
  5. Ignoring test failures - Broken windows effect
  6. Testing private methods - Coupling to implementation
  7. No assertion - Tests that can't fail
  8. Copy-paste tests - Maintenance nightmare

Quick Reference

PYRAMID:
  Unit (70%) → Integration (20%) → E2E (10%)

TDD CYCLE:
  Red → Green → Refactor

PATTERNS:
  AAA: Arrange-Act-Assert
  Builder: Fluent test data creation
  Page Object: E2E abstraction

MOCK WHEN:
  External APIs, Database (unit), Time, Random

COVERAGE:
  70-80% line, focus on business logic

NAMING:
  test_[what]_[condition]_[expected]
提供Git工作流、分支策略(如Git Flow、GitHub Flow)、提交规范及版本控制最佳实践,用于管理仓库、创建分支和处理合并。
设置分支策略 编写提交信息 处理合并与冲突 管理发布流程 代码审查工作流 维护清晰的提交历史
skills/managing-git/SKILL.md
npx skills add CloudAI-X/opencode-workflow --skill managing-git -g -y
SKILL.md
Frontmatter
{
    "name": "managing-git",
    "license": "MIT",
    "metadata": {
        "audience": "developers",
        "category": "workflow"
    },
    "description": "Guides git workflows, branching strategies, commit conventions, and version control best practices. Use when managing repositories, creating branches, or handling merges.",
    "compatibility": "opencode"
}

Managing Git

Best practices for version control, branching strategies, and collaborative development.

When to Use This Skill

  • Setting up branching strategies
  • Writing commit messages
  • Handling merges and conflicts
  • Managing releases
  • Code review workflows
  • Maintaining clean history

Branching Strategies

Git Flow

main ─────●─────────────────────●─────────────────●────▶
           \                   /                 /
release     \───────●─────────●                 /
              \                                /
develop ───────●───────●───────●──────●───────●────────▶
                \       \       \      \
feature          \───────●───────●      \───●───●
                          \              \
hotfix                     \              \───●────▶ main
Branch Purpose Branches From Merges Into
main Production code - -
develop Integration main release
feature/* New features develop develop
release/* Release prep develop main, develop
hotfix/* Production fixes main main, develop

Use when: Scheduled releases, multiple versions supported

GitHub Flow

main ─────●─────●─────●─────●─────●────▶
           \   /       \   /       \   /
feature     ●─●         ●─●         ●─●
            PR          PR          PR
Branch Purpose
main Always deployable
feature/* All changes (features, fixes)

Use when: Continuous deployment, simple workflow

Trunk-Based Development

main ─────●──●──●──●──●──●──●──●──●──●────▶
           │  │  │  │  │  │  │  │  │  │
          ●   ●  ●  ●  ●  ●  ●  ●  ●  ●
          Small, frequent commits (often direct to main)

Use when: High trust teams, strong CI/CD, frequent deploys


Commit Message Conventions

Conventional Commits

<type>(<scope>): <subject>

<body>

<footer>

Types

Type Description Example
feat New feature feat(auth): add OAuth2 login
fix Bug fix fix(api): handle null response
docs Documentation docs(readme): update setup steps
style Formatting style: fix indentation
refactor Code restructuring refactor(db): simplify query builder
test Adding tests test(user): add registration tests
chore Maintenance chore(deps): update lodash
perf Performance perf(search): add index on email
ci CI/CD changes ci: add Node 18 to matrix

Good vs Bad Commits

BAD:
  - "fix"
  - "update code"
  - "WIP"
  - "changes"
  - "asdfasdf"

GOOD:
  - "fix(auth): prevent session timeout on idle"
  - "feat(cart): add quantity validation"
  - "refactor(api): extract common error handling"

Commit Body Guidelines

fix(payment): prevent double charge on retry

The payment gateway timeout was causing the retry logic to submit
duplicate charges. Added idempotency key to prevent double-processing.

Closes #1234
  • First line: 50 chars max, imperative mood
  • Body: Wrap at 72 chars, explain why, not what
  • Footer: Reference issues, breaking changes

Branch Naming Conventions

Pattern

<type>/<ticket>-<short-description>

Examples

Type Example
Feature feature/AUTH-123-add-oauth-login
Bugfix fix/CART-456-quantity-validation
Hotfix hotfix/PROD-789-memory-leak
Chore chore/update-dependencies
Docs docs/api-documentation

Branch Rules

  1. Lowercase with hyphens
  2. Include ticket number when available
  3. Keep short but descriptive
  4. Delete after merge

Git Workflow Commands

Daily Workflow

# Start new feature
git checkout main
git pull origin main
git checkout -b feature/AUTH-123-add-login

# Work on feature
git add -p                    # Stage hunks interactively
git commit -m "feat(auth): add login form"

# Keep up to date
git fetch origin
git rebase origin/main        # Preferred: clean history
# OR
git merge origin/main         # Alternative: preserves context

# Push and create PR
git push -u origin feature/AUTH-123-add-login

Useful Commands

Command Purpose
git stash Save uncommitted changes temporarily
git stash pop Restore stashed changes
git commit --amend Modify last commit
git rebase -i HEAD~3 Interactive rebase (squash, reorder)
git cherry-pick <sha> Apply specific commit
git bisect Binary search for bug introduction
git reflog View all HEAD movements (recovery)

Cleanup Commands

# Delete merged branches locally
git branch --merged | grep -v main | xargs git branch -d

# Prune remote tracking branches
git fetch --prune

# Clean untracked files (careful!)
git clean -fd

Handling Conflicts

Conflict Resolution Flow

1. Identify conflicts
   git status

2. Open conflicted files
   <<<<<<< HEAD
   your changes
   =======
   their changes
   >>>>>>> feature-branch

3. Resolve (keep one, combine, or rewrite)

4. Mark resolved
   git add <resolved-file>

5. Continue
   git rebase --continue   # if rebasing
   git commit              # if merging

Prevention Strategies

  1. Small, frequent merges - Reduce conflict scope
  2. Communication - Coordinate on shared files
  3. Feature flags - Reduce long-lived branches
  4. Clear ownership - Minimize overlapping work

Pull Request Best Practices

PR Checklist

  • Branch is up to date with main
  • Tests pass locally
  • Linting passes
  • Self-review completed
  • Documentation updated
  • Ticket/issue linked
  • Screenshots for UI changes

PR Size Guidelines

Size Lines Changed Review Time Recommendation
Small 1-100 15 min Ideal
Medium 100-400 30-60 min Acceptable
Large 400+ 1+ hour Split if possible

PR Description Template

## Summary
Brief description of changes

## Changes
- Added X
- Modified Y
- Removed Z

## Testing
- [ ] Unit tests added
- [ ] Manual testing done

## Screenshots (if applicable)
[Before/After images]

## Related Issues
Closes #123

Release Management

Semantic Versioning

MAJOR.MINOR.PATCH
  │     │     │
  │     │     └── Bug fixes (backward compatible)
  │     └── New features (backward compatible)
  └── Breaking changes

Release Process

# Create release branch
git checkout -b release/v1.2.0 develop

# Bump version, update changelog
# ... make changes ...

# Merge to main and tag
git checkout main
git merge release/v1.2.0
git tag -a v1.2.0 -m "Release v1.2.0"
git push origin main --tags

# Merge back to develop
git checkout develop
git merge release/v1.2.0

Changelog Format

# Changelog

## [1.2.0] - 2024-01-15
### Added
- OAuth2 authentication support

### Changed
- Improved error messages

### Fixed
- Memory leak in cache handler

### Deprecated
- Old authentication method (use OAuth2)

### Removed
- Legacy API v1 endpoints

Git Hooks

Common Hooks

Hook Timing Use Case
pre-commit Before commit Linting, formatting
commit-msg After message Validate message format
pre-push Before push Run tests
post-merge After merge Install dependencies

Example pre-commit

#!/bin/sh
# .git/hooks/pre-commit

# Run linter
npm run lint
if [ $? -ne 0 ]; then
  echo "Linting failed. Please fix errors."
  exit 1
fi

# Run tests
npm test
if [ $? -ne 0 ]; then
  echo "Tests failed. Please fix before committing."
  exit 1
fi

Using Husky (Node.js)

// package.json
{
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged",
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
    }
  }
}

Troubleshooting

Common Issues

Problem Solution
Accidental commit to main git reset HEAD~1 (before push)
Wrong branch git stash, switch, git stash pop
Need to undo merge git revert -m 1 <merge-commit>
Lost commits git reflog to find, git cherry-pick
Large file committed git filter-branch or BFG Repo-Cleaner

Recovery Commands

# Undo last commit (keep changes)
git reset --soft HEAD~1

# Undo last commit (discard changes)
git reset --hard HEAD~1

# Recover deleted branch
git reflog
git checkout -b recovered-branch <sha>

# Undo a pushed commit (safe)
git revert <sha>

Anti-Patterns to Avoid

  1. Force pushing to shared branches - Breaks others' history
  2. Giant commits - Hard to review, hard to bisect
  3. Vague commit messages - "fix" tells nothing
  4. Long-lived branches - Merge conflict hell
  5. Committing generated files - Bloats repo, causes conflicts
  6. Committing secrets - Security risk (even after removal)
  7. Rebasing public history - Breaks collaborators
  8. Ignoring CI failures - Broken windows effect

Quick Reference

BRANCHES:
  main       → Production (protected)
  develop    → Integration (Git Flow)
  feature/*  → New work
  fix/*      → Bug fixes
  hotfix/*   → Production emergencies

COMMITS:
  feat(scope): add feature
  fix(scope): fix bug
  docs(scope): update docs
  refactor(scope): restructure code

DAILY FLOW:
  git checkout -b feature/ticket-desc
  git add -p && git commit
  git rebase origin/main
  git push -u origin feature/ticket-desc

VERSIONING:
  MAJOR.MINOR.PATCH
  Breaking.Feature.Bugfix
指导性能优化、剖析技术及瓶颈识别。适用于提升应用速度、降低资源消耗或诊断性能问题,涵盖测量原则、剖析工作流及常见瓶颈模式解决方案。
应用程序运行缓慢 CPU或内存等资源消耗过高 数据库查询响应慢 API响应延迟高 需要为更多用户进行扩展 准备负载测试
skills/optimizing-performance/SKILL.md
npx skills add CloudAI-X/opencode-workflow --skill optimizing-performance -g -y
SKILL.md
Frontmatter
{
    "name": "optimizing-performance",
    "license": "MIT",
    "metadata": {
        "audience": "developers",
        "category": "quality"
    },
    "description": "Guides performance optimization, profiling techniques, and bottleneck identification. Use when improving application speed, reducing resource usage, or diagnosing performance issues.",
    "compatibility": "opencode"
}

Optimizing Performance

Strategies for identifying, analyzing, and resolving performance bottlenecks.

When to Use This Skill

  • Application is running slowly
  • High resource consumption (CPU, memory)
  • Database queries are slow
  • API response times are high
  • Need to scale for more users
  • Preparing for load testing

Performance Optimization Philosophy

The Golden Rules

  1. Measure first - Never optimize without data
  2. Optimize the right thing - Find the actual bottleneck
  3. Keep it simple - Complexity often hurts performance
  4. Test after - Verify the optimization worked
  5. Document trade-offs - Performance often costs readability

The 80/20 Rule

80% of performance problems come from 20% of the code.

Focus on:
├── Hot paths (frequently executed code)
├── I/O operations (database, network, disk)
├── Memory allocation patterns
└── Algorithm complexity

Profiling Techniques

Types of Profiling

Type What It Measures Tools
CPU Profiling Time spent in functions pprof, py-spy, Chrome DevTools
Memory Profiling Allocation patterns, leaks Valgrind, memory_profiler, Chrome
I/O Profiling Disk/network operations strace, perf, Wireshark
Database Profiling Query performance EXPLAIN, slow query log, APM

Profiling Workflow

1. Establish baseline
   └─ Measure current performance with realistic load

2. Identify hotspots
   └─ Profile to find where time/resources are spent

3. Form hypothesis
   └─ Why is this slow? What would make it faster?

4. Implement fix
   └─ Make ONE change at a time

5. Measure again
   └─ Did it help? By how much?

6. Repeat
   └─ Until performance goals are met

Common Profiling Commands

# Node.js
node --prof app.js
node --prof-process isolate-*.log > profile.txt

# Python
python -m cProfile -s cumtime app.py
py-spy record -o profile.svg -- python app.py

# Go
go test -cpuprofile cpu.prof -memprofile mem.prof -bench .
go tool pprof cpu.prof

# Database (PostgreSQL)
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'test@example.com';

Common Bottleneck Patterns

N+1 Query Problem

BAD (N+1 queries):
  SELECT * FROM posts;             -- 1 query
  SELECT * FROM users WHERE id=1;  -- N queries
  SELECT * FROM users WHERE id=2;
  ...

GOOD (2 queries):
  SELECT * FROM posts;
  SELECT * FROM users WHERE id IN (1, 2, 3, ...);

Detection: High query count relative to data returned Fix: Eager loading, batch fetching, JOINs

Unbounded Operations

BAD:
  SELECT * FROM logs;  -- Returns millions of rows

GOOD:
  SELECT * FROM logs
  WHERE created_at > NOW() - INTERVAL '1 day'
  LIMIT 100;

Detection: Memory spikes, timeouts Fix: Pagination, limits, streaming

Synchronous Blocking

BAD (blocking):
  result1 = fetch_api_1()  -- Wait 200ms
  result2 = fetch_api_2()  -- Wait 200ms
  return combine(result1, result2)  -- Total: 400ms

GOOD (parallel):
  [result1, result2] = await Promise.all([
    fetch_api_1(),
    fetch_api_2()
  ])  -- Total: ~200ms

Detection: Sequential I/O in traces Fix: Parallel execution, async/await

Excessive Allocation

BAD (allocates in loop):
  for item in large_list:
      result = []  # Allocates each iteration
      result.append(transform(item))

GOOD (pre-allocate):
  result = []
  for item in large_list:
      result.append(transform(item))

BEST (generator):
  def transform_all(items):
      for item in items:
          yield transform(item)

Detection: GC pressure, memory profiling Fix: Object pooling, pre-allocation, generators


Optimization Techniques

Database Optimization

Technique When to Use Impact
Indexing Slow WHERE/JOIN queries High
Query optimization Complex queries High
Connection pooling Many short connections Medium
Read replicas Read-heavy workloads High
Caching Repeated queries Very High
Denormalization Complex JOINs Medium

Index Guidelines

-- Create index for frequently queried columns
CREATE INDEX idx_users_email ON users(email);

-- Composite index for multiple column queries
CREATE INDEX idx_orders_user_date ON orders(user_id, created_at);

-- Check if index is used
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'test@example.com';

Caching Strategies

Strategy Use Case Invalidation
Cache-aside General purpose Manual or TTL
Write-through Strong consistency On write
Write-behind Write-heavy Async batched
Read-through Read-heavy On miss
Cache-aside pattern:
1. Check cache
2. If miss, query database
3. Store in cache
4. Return result

Memory Optimization

Technique When to Use
Object pooling Frequent allocation of same type
Lazy loading Large objects not always needed
Streaming Processing large datasets
Weak references Cache that can be evicted
Data structure choice Right structure for access pattern

Frontend Performance

Core Web Vitals

Metric Target What It Measures
LCP (Largest Contentful Paint) < 2.5s Load performance
INP (Interaction to Next Paint) < 200ms Interactivity
CLS (Cumulative Layout Shift) < 0.1 Visual stability

Frontend Optimization Checklist

Loading Performance:
  ☐ Code splitting (lazy load routes/components)
  ☐ Tree shaking (remove unused code)
  ☐ Minification (JS, CSS)
  ☐ Compression (gzip, brotli)
  ☐ Image optimization (WebP, srcset, lazy loading)
  ☐ CDN for static assets

Runtime Performance:
  ☐ Virtualized lists for large data
  ☐ Debounce/throttle event handlers
  ☐ Memoization of expensive computations
  ☐ Avoid layout thrashing (batch DOM reads/writes)
  ☐ Use CSS transforms for animations
  ☐ Web Workers for heavy computation

Bundle Optimization

# Analyze bundle size
npx webpack-bundle-analyzer stats.json
npx source-map-explorer bundle.js

# Identify large dependencies
npx depcheck

API Performance

Response Time Targets

Percentile Target User Experience
p50 < 100ms Fast
p95 < 500ms Acceptable
p99 < 1s Tolerable

API Optimization Techniques

Technique Benefit
Response compression Reduce transfer size
Pagination Limit response size
Field selection Return only needed data
ETags/Caching headers Reduce redundant requests
Connection keep-alive Reduce handshake overhead
HTTP/2 Multiplexing, header compression

Batch Endpoints

BAD (multiple requests):
  GET /users/1
  GET /users/2
  GET /users/3

GOOD (batch):
  POST /users/batch
  { "ids": [1, 2, 3] }

Monitoring and Alerting

Key Metrics to Track

Category Metrics
Latency p50, p95, p99 response times
Throughput Requests per second
Errors Error rate, error types
Saturation CPU, memory, connections

Alerting Thresholds

Critical (page immediately):
  - Error rate > 5%
  - p99 latency > 5s
  - Service down

Warning (notify during hours):
  - Error rate > 1%
  - p95 latency > 2s
  - Resource utilization > 80%

Logging for Performance

# Log slow operations
import time
import logging

def timed_operation(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        duration = time.time() - start
        if duration > 1.0:  # Log if > 1 second
            logging.warning(f"{func.__name__} took {duration:.2f}s")
        return result
    return wrapper

Performance Testing

Load Testing Tools

Tool Use Case
k6 Modern, scriptable load testing
JMeter Complex scenarios, GUI
Locust Python-based, distributed
Artillery YAML config, easy to start
wrk Simple HTTP benchmarking

Load Test Example (k6)

import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  stages: [
    { duration: '1m', target: 50 },   // Ramp up
    { duration: '5m', target: 50 },   // Stay at 50 users
    { duration: '1m', target: 0 },    // Ramp down
  ],
  thresholds: {
    http_req_duration: ['p(95)<500'],  // 95% under 500ms
    http_req_failed: ['rate<0.01'],    // Error rate < 1%
  },
};

export default function () {
  const res = http.get('https://api.example.com/users');
  check(res, { 'status is 200': (r) => r.status === 200 });
  sleep(1);
}

Anti-Patterns to Avoid

  1. Premature optimization - Optimize only proven bottlenecks
  2. Optimizing without measuring - Guessing wastes time
  3. Over-caching - Cache invalidation is hard
  4. Ignoring database - Often the real bottleneck
  5. Complex micro-optimizations - Usually not worth it
  6. Not testing under load - Production behavior differs
  7. Ignoring cold starts - First request matters too
  8. Over-engineering - Simpler is often faster

Quick Reference

PROFILING FLOW:
  Measure → Identify → Hypothesize → Fix → Measure → Repeat

COMMON BOTTLENECKS:
  N+1 queries → Eager loading
  Unbounded data → Pagination
  Blocking I/O → Parallelization
  Excessive allocation → Object pooling

DATABASE:
  Index frequently queried columns
  Use EXPLAIN ANALYZE
  Add caching layer

CACHING:
  Cache-aside for general use
  TTL for time-based invalidation
  Invalidate on write for consistency

TARGETS:
  p50 < 100ms
  p95 < 500ms
  p99 < 1s

TOOLS:
  CPU: pprof, py-spy
  Memory: valgrind, memory_profiler
  Load: k6, locust
  DB: EXPLAIN, slow query log
指导如何在单条消息中并行发起多个Task调用,避免串行执行导致的低效。适用于独立任务、多目录分析或多视角审查场景,通过并发处理显著提升系统吞吐量与执行速度。
需要同时执行多个互不依赖的任务 对代码库不同部分进行并行分析 需要从多个角度同时进行代码审查
skills/parallel-execution/SKILL.md
npx skills add CloudAI-X/opencode-workflow --skill parallel-execution -g -y
SKILL.md
Frontmatter
{
    "name": "parallel-execution",
    "license": "MIT",
    "metadata": {
        "audience": "agents",
        "category": "workflow"
    },
    "description": "CRITICAL skill for executing multiple Task tool calls in a SINGLE message for true parallelism. Essential for efficient multi-task workflows, subagent coordination, and maximizing throughput.",
    "compatibility": "opencode"
}

Parallel Execution

CRITICAL: This skill teaches how to execute multiple tasks simultaneously for maximum efficiency.

The Fundamental Rule

ALL Task calls MUST be in a SINGLE assistant message for true parallelism.

If Task calls are in separate messages, they run SEQUENTIALLY, not in parallel.


Why Parallel Execution Matters

Sequential (SLOW - AVOID)

Message 1: Start Task A
           ↓ wait for completion
Message 2: Start Task B
           ↓ wait for completion
Message 3: Start Task C
           ↓ wait for completion

Total time = A + B + C = 90 seconds (if each takes 30s)

Parallel (FAST - USE THIS)

Message 1: Start Task A ─┐
           Start Task B ─┼─ All run simultaneously
           Start Task C ─┘

Total time ≈ max(A, B, C) = 30 seconds

Speedup: 3x faster with 3 parallel tasks


How to Execute in Parallel

Step 1: Identify Independent Tasks

Tasks are independent when:

  • They don't depend on each other's output
  • They don't modify the same files
  • They can run in any order

Step 2: Launch ALL Tasks in ONE Message

<!-- CORRECT: All tasks in single message = PARALLEL -->
<task>
  <description>Analyze authentication module</description>
  <prompt>Review src/auth for security patterns...</prompt>
</task>

<task>
  <description>Analyze API layer</description>
  <prompt>Review src/api for REST best practices...</prompt>
</task>

<task>
  <description>Analyze database layer</description>
  <prompt>Review src/db for query optimization...</prompt>
</task>

Step 3: Collect and Synthesize Results

After all tasks complete, combine their findings into a unified response.


Parallelization Patterns

Pattern 1: Task-Based Parallelization

When you have N independent tasks, spawn N subagents:

Implementation Plan:
1. Implement auth module
2. Create API endpoints
3. Add database schema
4. Write unit tests
5. Update documentation

Launch 5 parallel subagents:
├─ Subagent 1: Implement auth module
├─ Subagent 2: Create API endpoints
├─ Subagent 3: Add database schema
├─ Subagent 4: Write unit tests
└─ Subagent 5: Update documentation

All 5 in ONE message!

Pattern 2: Directory-Based Parallelization

Analyze different directories simultaneously:

Codebase Structure:
├── src/auth/
├── src/api/
├── src/db/
└── src/ui/

Launch 4 parallel subagents:
├─ Subagent 1: Analyze src/auth
├─ Subagent 2: Analyze src/api
├─ Subagent 3: Analyze src/db
└─ Subagent 4: Analyze src/ui

Pattern 3: Perspective-Based Parallelization

Review from multiple angles at once:

Code Review Perspectives:
- Security vulnerabilities
- Performance bottlenecks
- Test coverage gaps
- Architecture patterns

Launch 4 parallel subagents:
├─ Subagent 1: Security review
├─ Subagent 2: Performance analysis
├─ Subagent 3: Test coverage review
└─ Subagent 4: Architecture assessment

Pattern 4: Adversarial Verification

Use conflicting mandates for thorough review:

Verification Subagents (all parallel):
├─ Syntax & Type Checker
├─ Test Runner
├─ Lint & Style Checker
├─ Security Scanner
└─ Build Validator

Then (sequential, after above complete):
├─ False Positive Filter
├─ Missing Issues Finder
└─ Context Validator

TodoWrite Integration

When using parallel execution, mark ALL parallel tasks as in_progress simultaneously:

Before Launching Parallel Tasks

{
  "todos": [
    { "content": "Analyze auth module", "status": "in_progress", "activeForm": "Analyzing auth module" },
    { "content": "Analyze API layer", "status": "in_progress", "activeForm": "Analyzing API layer" },
    { "content": "Analyze database layer", "status": "in_progress", "activeForm": "Analyzing database layer" },
    { "content": "Synthesize findings", "status": "pending", "activeForm": "Synthesizing findings" }
  ]
}

After Each Task Completes

Mark as completed as results come in:

{
  "todos": [
    { "content": "Analyze auth module", "status": "completed", "activeForm": "Analyzing auth module" },
    { "content": "Analyze API layer", "status": "completed", "activeForm": "Analyzing API layer" },
    { "content": "Analyze database layer", "status": "in_progress", "activeForm": "Analyzing database layer" },
    { "content": "Synthesize findings", "status": "pending", "activeForm": "Synthesizing findings" }
  ]
}

When to Parallelize

Good Candidates

Scenario Parallel Approach
Multiple independent analyses One subagent per analysis
Multi-file processing One subagent per file/directory
Different review perspectives One subagent per perspective
Multiple independent features One subagent per feature
Exploratory research Multiple search strategies

When NOT to Parallelize

Scenario Why Sequential
Tasks with dependencies B needs A's output
Same file modifications Risk of conflicts
Sequential workflows Order matters (commit → push → PR)
Shared state Race conditions
Limited resources Overwhelming the system

Performance Impact

# Parallel Tasks Sequential Time Parallel Time Speedup
2 60s 30s 2x
3 90s 30s 3x
5 150s 30s 5x
10 300s 30s 10x

Assuming each task takes ~30 seconds


Common Mistakes

Mistake 1: Separate Messages

WRONG (Sequential):
Message 1: "I'll start analyzing the auth module..."
           <task>Analyze auth</task>
Message 2: "Now let me analyze the API..."
           <task>Analyze API</task>

RIGHT (Parallel):
Message 1: "I'll analyze all modules in parallel..."
           <task>Analyze auth</task>
           <task>Analyze API</task>
           <task>Analyze DB</task>

Mistake 2: Announcing Before Acting

WRONG:
"I'm going to launch three parallel tasks to analyze the codebase."
[waits for response]
"Now launching the tasks..."

RIGHT:
"Launching three parallel analysis tasks now:"
<task>...</task>
<task>...</task>
<task>...</task>

Mistake 3: Forgetting Synthesis

WRONG:
Just dump all task outputs without integration

RIGHT:
After receiving all results, synthesize:
- Identify common themes
- Resolve contradictions
- Prioritize findings
- Create unified recommendations

Parallel Execution Checklist

Before launching parallel tasks, verify:

  • Tasks are truly independent
  • No shared file modifications
  • No sequential dependencies
  • All tasks in SINGLE message
  • TodoWrite updated with all in_progress
  • Synthesis step planned

Template: Parallel Analysis

## Launching Parallel Analysis

I'm analyzing this codebase from multiple perspectives simultaneously.

### Parallel Tasks

<task description="Security Review">
Analyze for security vulnerabilities, focusing on:
- Authentication/authorization
- Input validation
- Secrets handling
</task>

<task description="Performance Review">
Analyze for performance issues, focusing on:
- N+1 queries
- Memory leaks
- Blocking operations
</task>

<task description="Test Coverage Review">
Analyze test coverage, focusing on:
- Missing test cases
- Edge cases
- Integration tests
</task>

### Synthesis (after all complete)

[Combine findings into prioritized report]

Quick Reference

RULE #1:
  ALL Task calls in SINGLE message = PARALLEL
  Task calls in SEPARATE messages = SEQUENTIAL

PATTERNS:
  Task-based:       One subagent per task
  Directory-based:  One subagent per directory
  Perspective-based: One subagent per viewpoint
  Adversarial:      Multiple competing reviewers

TODOWRITE:
  Mark ALL parallel tasks as in_progress BEFORE launching
  Mark each as completed AFTER receiving results

SPEEDUP:
  N parallel tasks ≈ Nx faster
  (5 tasks @ 30s each: 150s → 30s)

CHECKLIST:
  ☐ Tasks independent?
  ☐ No shared files?
  ☐ No dependencies?
  ☐ All in ONE message?
  ☐ Synthesis planned?

Accueil - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-07-08 17:44
浙ICP备14020137号-1 $Carte des visiteurs$