feat: add Conductor plugin for Context-Driven Development

Add comprehensive Conductor plugin implementing Context-Driven Development
methodology with tracks, specs, and phased implementation plans.

Components:
- 5 commands: setup, new-track, implement, status, revert
- 1 agent: conductor-validator
- 3 skills: context-driven-development, track-management, workflow-patterns
- 18 templates for project artifacts

Documentation updates:
- README.md: Updated counts (68 plugins, 100 agents, 110 skills, 76 tools)
- docs/plugins.md: Added Conductor to Workflows section
- docs/agents.md: Added conductor-validator agent
- docs/agent-skills.md: Added Conductor skills section

Also includes Prettier formatting across all project files.
This commit is contained in:
Seth Hobson
2026-01-15 17:38:21 -05:00
parent 87231b828d
commit f662524f9a
94 changed files with 11610 additions and 1728 deletions

View File

@@ -22,12 +22,14 @@ Master REST and GraphQL API design principles to build intuitive, scalable, and
### 1. RESTful Design Principles
**Resource-Oriented Architecture**
- Resources are nouns (users, orders, products), not verbs
- Use HTTP methods for actions (GET, POST, PUT, PATCH, DELETE)
- URLs represent resource hierarchies
- Consistent naming conventions
**HTTP Methods Semantics:**
- `GET`: Retrieve resources (idempotent, safe)
- `POST`: Create new resources
- `PUT`: Replace entire resource (idempotent)
@@ -37,12 +39,14 @@ Master REST and GraphQL API design principles to build intuitive, scalable, and
### 2. GraphQL Design Principles
**Schema-First Development**
- Types define your domain model
- Queries for reading data
- Mutations for modifying data
- Subscriptions for real-time updates
**Query Structure:**
- Clients request exactly what they need
- Single endpoint, multiple operations
- Strongly typed schema
@@ -51,17 +55,20 @@ Master REST and GraphQL API design principles to build intuitive, scalable, and
### 3. API Versioning Strategies
**URL Versioning:**
```
/api/v1/users
/api/v2/users
```
**Header Versioning:**
```
Accept: application/vnd.api+json; version=1
```
**Query Parameter Versioning:**
```
/api/users?version=1
```
@@ -256,11 +263,7 @@ type User {
createdAt: DateTime!
# Relationships
orders(
first: Int = 20
after: String
status: OrderStatus
): OrderConnection!
orders(first: Int = 20, after: String, status: OrderStatus): OrderConnection!
profile: UserProfile
}
@@ -311,11 +314,7 @@ scalar Money
# Query root
type Query {
user(id: ID!): User
users(
first: Int = 20
after: String
search: String
): UserConnection!
users(first: Int = 20, after: String, search: String): UserConnection!
order(id: ID!): Order
}
@@ -489,6 +488,7 @@ def create_context():
## Best Practices
### REST APIs
1. **Consistent Naming**: Use plural nouns for collections (`/users`, not `/user`)
2. **Stateless**: Each request contains all necessary information
3. **Use HTTP Status Codes Correctly**: 2xx success, 4xx client errors, 5xx server errors
@@ -498,6 +498,7 @@ def create_context():
7. **Documentation**: Use OpenAPI/Swagger for interactive docs
### GraphQL APIs
1. **Schema First**: Design schema before writing resolvers
2. **Avoid N+1**: Use DataLoaders for efficient data fetching
3. **Input Validation**: Validate at schema and resolver levels

View File

@@ -3,6 +3,7 @@
## Pre-Implementation Review
### Resource Design
- [ ] Resources are nouns, not verbs
- [ ] Plural names for collections
- [ ] Consistent naming across all endpoints
@@ -10,6 +11,7 @@
- [ ] All CRUD operations properly mapped to HTTP methods
### HTTP Methods
- [ ] GET for retrieval (safe, idempotent)
- [ ] POST for creation
- [ ] PUT for full replacement (idempotent)
@@ -17,6 +19,7 @@
- [ ] DELETE for removal (idempotent)
### Status Codes
- [ ] 200 OK for successful GET/PATCH/PUT
- [ ] 201 Created for POST
- [ ] 204 No Content for DELETE
@@ -29,6 +32,7 @@
- [ ] 500 Internal Server Error for server issues
### Pagination
- [ ] All collection endpoints paginated
- [ ] Default page size defined (e.g., 20)
- [ ] Maximum page size enforced (e.g., 100)
@@ -36,17 +40,20 @@
- [ ] Cursor-based or offset-based pattern chosen
### Filtering & Sorting
- [ ] Query parameters for filtering
- [ ] Sort parameter supported
- [ ] Search parameter for full-text search
- [ ] Field selection supported (sparse fieldsets)
### Versioning
- [ ] Versioning strategy defined (URL/header/query)
- [ ] Version included in all endpoints
- [ ] Deprecation policy documented
### Error Handling
- [ ] Consistent error response format
- [ ] Detailed error messages
- [ ] Field-level validation errors
@@ -54,18 +61,21 @@
- [ ] Timestamps in error responses
### Authentication & Authorization
- [ ] Authentication method defined (Bearer token, API key)
- [ ] Authorization checks on all endpoints
- [ ] 401 vs 403 used correctly
- [ ] Token expiration handled
### Rate Limiting
- [ ] Rate limits defined per endpoint/user
- [ ] Rate limit headers included
- [ ] 429 status code for exceeded limits
- [ ] Retry-After header provided
### Documentation
- [ ] OpenAPI/Swagger spec generated
- [ ] All endpoints documented
- [ ] Request/response examples provided
@@ -73,6 +83,7 @@
- [ ] Authentication flow documented
### Testing
- [ ] Unit tests for business logic
- [ ] Integration tests for endpoints
- [ ] Error scenarios tested
@@ -80,6 +91,7 @@
- [ ] Performance tests for heavy endpoints
### Security
- [ ] Input validation on all fields
- [ ] SQL injection prevention
- [ ] XSS prevention
@@ -89,6 +101,7 @@
- [ ] No secrets in responses
### Performance
- [ ] Database queries optimized
- [ ] N+1 queries prevented
- [ ] Caching strategy defined
@@ -96,6 +109,7 @@
- [ ] Large responses paginated
### Monitoring
- [ ] Logging implemented
- [ ] Error tracking configured
- [ ] Performance metrics collected
@@ -105,6 +119,7 @@
## GraphQL-Specific Checks
### Schema Design
- [ ] Schema-first approach used
- [ ] Types properly defined
- [ ] Non-null vs nullable decided
@@ -112,24 +127,28 @@
- [ ] Custom scalars defined
### Queries
- [ ] Query depth limiting
- [ ] Query complexity analysis
- [ ] DataLoaders prevent N+1
- [ ] Pagination pattern chosen (Relay/offset)
### Mutations
- [ ] Input types defined
- [ ] Payload types with errors
- [ ] Optimistic response support
- [ ] Idempotency considered
### Performance
- [ ] DataLoader for all relationships
- [ ] Query batching enabled
- [ ] Persisted queries considered
- [ ] Response caching implemented
### Documentation
- [ ] All fields documented
- [ ] Deprecations marked
- [ ] Examples provided

View File

@@ -3,6 +3,7 @@
## Schema Organization
### Modular Schema Structure
```graphql
# user.graphql
type User {
@@ -37,17 +38,19 @@ extend type Query {
## Type Design Patterns
### 1. Non-Null Types
```graphql
type User {
id: ID! # Always required
email: String! # Required
phone: String # Optional (nullable)
posts: [Post!]! # Non-null array of non-null posts
tags: [String!] # Nullable array of non-null strings
id: ID! # Always required
email: String! # Required
phone: String # Optional (nullable)
posts: [Post!]! # Non-null array of non-null posts
tags: [String!] # Nullable array of non-null strings
}
```
### 2. Interfaces for Polymorphism
```graphql
interface Node {
id: ID!
@@ -72,6 +75,7 @@ type Query {
```
### 3. Unions for Heterogeneous Results
```graphql
union SearchResult = User | Post | Comment
@@ -92,13 +96,16 @@ type Query {
}
... on Comment {
text
author { name }
author {
name
}
}
}
}
```
### 4. Input Types
```graphql
input CreateUserInput {
email: String!
@@ -124,6 +131,7 @@ input UpdateUserInput {
## Pagination Patterns
### Relay Cursor Pagination (Recommended)
```graphql
type UserConnection {
edges: [UserEdge!]!
@@ -144,12 +152,7 @@ type PageInfo {
}
type Query {
users(
first: Int
after: String
last: Int
before: String
): UserConnection!
users(first: Int, after: String, last: Int, before: String): UserConnection!
}
# Usage
@@ -171,6 +174,7 @@ type Query {
```
### Offset Pagination (Simpler)
```graphql
type UserList {
items: [User!]!
@@ -187,6 +191,7 @@ type Query {
## Mutation Design Patterns
### 1. Input/Payload Pattern
```graphql
input CreatePostInput {
title: String!
@@ -212,6 +217,7 @@ type Mutation {
```
### 2. Optimistic Response Support
```graphql
type UpdateUserPayload {
user: User
@@ -231,6 +237,7 @@ type Mutation {
```
### 3. Batch Mutations
```graphql
input BatchCreateUserInput {
users: [CreateUserInput!]!
@@ -256,6 +263,7 @@ type Mutation {
## Field Design
### Arguments and Filtering
```graphql
type Query {
posts(
@@ -296,20 +304,20 @@ enum OrderDirection {
```
### Computed Fields
```graphql
type User {
firstName: String!
lastName: String!
fullName: String! # Computed in resolver
fullName: String! # Computed in resolver
posts: [Post!]!
postCount: Int! # Computed, doesn't load all posts
postCount: Int! # Computed, doesn't load all posts
}
type Post {
likeCount: Int!
commentCount: Int!
isLikedByViewer: Boolean! # Context-dependent
isLikedByViewer: Boolean! # Context-dependent
}
```
@@ -366,6 +374,7 @@ type Product {
## Directives
### Built-in Directives
```graphql
type User {
name: String!
@@ -388,6 +397,7 @@ query GetUser($isOwner: Boolean!) {
```
### Custom Directives
```graphql
directive @auth(requires: Role = USER) on FIELD_DEFINITION
@@ -406,6 +416,7 @@ type Mutation {
## Error Handling
### Union Error Pattern
```graphql
type User {
id: ID!
@@ -452,6 +463,7 @@ type Query {
```
### Errors in Payload
```graphql
type CreateUserPayload {
user: User
@@ -476,6 +488,7 @@ enum ErrorCode {
## N+1 Query Problem Solutions
### DataLoader Pattern
```python
from aiodataloader import DataLoader
@@ -493,6 +506,7 @@ async def resolve_posts(user, info):
```
### Query Depth Limiting
```python
from graphql import GraphQLError
@@ -507,6 +521,7 @@ def depth_limit_validator(max_depth: int):
```
### Query Complexity Analysis
```python
def complexity_limit_validator(max_complexity: int):
def calculate_complexity(node):
@@ -522,6 +537,7 @@ def complexity_limit_validator(max_complexity: int):
## Schema Versioning
### Field Deprecation
```graphql
type User {
name: String! @deprecated(reason: "Use firstName and lastName")
@@ -531,6 +547,7 @@ type User {
```
### Schema Evolution
```graphql
# v1 - Initial
type User {

View File

@@ -3,6 +3,7 @@
## URL Structure
### Resource Naming
```
# Good - Plural nouns
GET /api/users
@@ -16,6 +17,7 @@ POST /api/createOrder
```
### Nested Resources
```
# Shallow nesting (preferred)
GET /api/users/{id}/orders
@@ -30,6 +32,7 @@ GET /api/order-items/{id}/reviews
## HTTP Methods and Status Codes
### GET - Retrieve Resources
```
GET /api/users → 200 OK (with list)
GET /api/users/{id} → 200 OK or 404 Not Found
@@ -37,6 +40,7 @@ GET /api/users?page=2 → 200 OK (paginated)
```
### POST - Create Resources
```
POST /api/users
Body: {"name": "John", "email": "john@example.com"}
@@ -50,6 +54,7 @@ POST /api/users (validation error)
```
### PUT - Replace Resources
```
PUT /api/users/{id}
Body: {complete user object}
@@ -60,6 +65,7 @@ PUT /api/users/{id}
```
### PATCH - Partial Update
```
PATCH /api/users/{id}
Body: {"name": "Jane"} (only changed fields)
@@ -68,6 +74,7 @@ PATCH /api/users/{id}
```
### DELETE - Remove Resources
```
DELETE /api/users/{id}
→ 204 No Content (deleted)
@@ -78,6 +85,7 @@ DELETE /api/users/{id}
## Filtering, Sorting, and Searching
### Query Parameters
```
# Filtering
GET /api/users?status=active
@@ -99,6 +107,7 @@ GET /api/users?fields=id,name,email
## Pagination Patterns
### Offset-Based Pagination
```python
GET /api/users?page=2&page_size=20
@@ -113,6 +122,7 @@ Response:
```
### Cursor-Based Pagination (for large datasets)
```python
GET /api/users?limit=20&cursor=eyJpZCI6MTIzfQ
@@ -125,6 +135,7 @@ Response:
```
### Link Header Pagination (RESTful)
```
GET /api/users?page=2
@@ -138,6 +149,7 @@ Link: <https://api.example.com/users?page=3>; rel="next",
## Versioning Strategies
### URL Versioning (Recommended)
```
/api/v1/users
/api/v2/users
@@ -147,6 +159,7 @@ Cons: Multiple URLs for same resource
```
### Header Versioning
```
GET /api/users
Accept: application/vnd.api+json; version=2
@@ -156,6 +169,7 @@ Cons: Less visible, harder to test
```
### Query Parameter
```
GET /api/users?version=2
@@ -166,6 +180,7 @@ Cons: Optional parameter can be forgotten
## Rate Limiting
### Headers
```
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 742
@@ -177,6 +192,7 @@ Retry-After: 3600
```
### Implementation Pattern
```python
from fastapi import HTTPException, Request
from datetime import datetime, timedelta
@@ -219,6 +235,7 @@ async def get_users(request: Request):
## Authentication and Authorization
### Bearer Token
```
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
@@ -227,6 +244,7 @@ Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
```
### API Keys
```
X-API-Key: your-api-key-here
```
@@ -234,6 +252,7 @@ X-API-Key: your-api-key-here
## Error Response Format
### Consistent Structure
```json
{
"error": {
@@ -253,6 +272,7 @@ X-API-Key: your-api-key-here
```
### Status Code Guidelines
- `200 OK`: Successful GET, PATCH, PUT
- `201 Created`: Successful POST
- `204 No Content`: Successful DELETE
@@ -269,6 +289,7 @@ X-API-Key: your-api-key-here
## Caching
### Cache Headers
```
# Client caching
Cache-Control: public, max-age=3600
@@ -285,6 +306,7 @@ If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
## Bulk Operations
### Batch Endpoints
```python
POST /api/users/batch
{
@@ -306,6 +328,7 @@ Response:
## Idempotency
### Idempotency Keys
```
POST /api/orders
Idempotency-Key: unique-key-123

View File

@@ -22,12 +22,14 @@ Master proven backend architecture patterns including Clean Architecture, Hexago
### 1. Clean Architecture (Uncle Bob)
**Layers (dependency flows inward):**
- **Entities**: Core business models
- **Use Cases**: Application business rules
- **Interface Adapters**: Controllers, presenters, gateways
- **Frameworks & Drivers**: UI, database, external services
**Key Principles:**
- Dependencies point inward
- Inner layers know nothing about outer layers
- Business logic independent of frameworks
@@ -36,11 +38,13 @@ Master proven backend architecture patterns including Clean Architecture, Hexago
### 2. Hexagonal Architecture (Ports and Adapters)
**Components:**
- **Domain Core**: Business logic
- **Ports**: Interfaces defining interactions
- **Adapters**: Implementations of ports (database, REST, message queue)
**Benefits:**
- Swap implementations easily (mock for testing)
- Technology-agnostic core
- Clear separation of concerns
@@ -48,11 +52,13 @@ Master proven backend architecture patterns including Clean Architecture, Hexago
### 3. Domain-Driven Design (DDD)
**Strategic Patterns:**
- **Bounded Contexts**: Separate models for different domains
- **Context Mapping**: How contexts relate
- **Ubiquitous Language**: Shared terminology
**Tactical Patterns:**
- **Entities**: Objects with identity
- **Value Objects**: Immutable objects defined by attributes
- **Aggregates**: Consistency boundaries
@@ -62,6 +68,7 @@ Master proven backend architecture patterns including Clean Architecture, Hexago
## Clean Architecture Pattern
### Directory Structure
```
app/
├── domain/ # Entities & business rules

View File

@@ -48,14 +48,14 @@ Comprehensive guide to implementing CQRS (Command Query Responsibility Segregati
### 2. Key Components
| Component | Responsibility |
|-----------|---------------|
| **Command** | Intent to change state |
| Component | Responsibility |
| ------------------- | ------------------------------- |
| **Command** | Intent to change state |
| **Command Handler** | Validates and executes commands |
| **Event** | Record of state change |
| **Query** | Request for data |
| **Query Handler** | Retrieves data from read model |
| **Projector** | Updates read model from events |
| **Event** | Record of state change |
| **Query** | Request for data |
| **Query Handler** | Retrieves data from read model |
| **Projector** | Updates read model from events |
## Templates
@@ -534,6 +534,7 @@ class ConsistentQueryHandler:
## Best Practices
### Do's
- **Separate command and query models** - Different needs
- **Use eventual consistency** - Accept propagation delay
- **Validate in command handlers** - Before state change
@@ -541,6 +542,7 @@ class ConsistentQueryHandler:
- **Version your events** - For schema evolution
### Don'ts
- **Don't query in commands** - Use only for writes
- **Don't couple read/write schemas** - Independent evolution
- **Don't over-engineer** - Start simple

View File

@@ -40,23 +40,23 @@ Comprehensive guide to designing event stores for event-sourced applications.
### 2. Event Store Requirements
| Requirement | Description |
|-------------|-------------|
| **Append-only** | Events are immutable, only appends |
| **Ordered** | Per-stream and global ordering |
| **Versioned** | Optimistic concurrency control |
| **Subscriptions** | Real-time event notifications |
| **Idempotent** | Handle duplicate writes safely |
| Requirement | Description |
| ----------------- | ---------------------------------- |
| **Append-only** | Events are immutable, only appends |
| **Ordered** | Per-stream and global ordering |
| **Versioned** | Optimistic concurrency control |
| **Subscriptions** | Real-time event notifications |
| **Idempotent** | Handle duplicate writes safely |
## Technology Comparison
| Technology | Best For | Limitations |
|------------|----------|-------------|
| **EventStoreDB** | Pure event sourcing | Single-purpose |
| **PostgreSQL** | Existing Postgres stack | Manual implementation |
| **Kafka** | High-throughput streaming | Not ideal for per-stream queries |
| **DynamoDB** | Serverless, AWS-native | Query limitations |
| **Marten** | .NET ecosystems | .NET specific |
| Technology | Best For | Limitations |
| ---------------- | ------------------------- | -------------------------------- |
| **EventStoreDB** | Pure event sourcing | Single-purpose |
| **PostgreSQL** | Existing Postgres stack | Manual implementation |
| **Kafka** | High-throughput streaming | Not ideal for per-stream queries |
| **DynamoDB** | Serverless, AWS-native | Query limitations |
| **Marten** | .NET ecosystems | .NET specific |
## Templates
@@ -416,6 +416,7 @@ Capacity: On-demand or provisioned based on throughput needs
## Best Practices
### Do's
- **Use stream IDs that include aggregate type** - `Order-{uuid}`
- **Include correlation/causation IDs** - For tracing
- **Version events from day one** - Plan for schema evolution
@@ -423,6 +424,7 @@ Capacity: On-demand or provisioned based on throughput needs
- **Index appropriately** - For your query patterns
### Don'ts
- **Don't update or delete events** - They're immutable facts
- **Don't store large payloads** - Keep events small
- **Don't skip optimistic concurrency** - Prevents data corruption

View File

@@ -22,16 +22,19 @@ Master microservices architecture patterns including service boundaries, inter-s
### 1. Service Decomposition Strategies
**By Business Capability**
- Organize services around business functions
- Each service owns its domain
- Example: OrderService, PaymentService, InventoryService
**By Subdomain (DDD)**
- Core domain, supporting subdomains
- Bounded contexts map to services
- Clear ownership and responsibility
**Strangler Fig Pattern**
- Gradually extract from monolith
- New functionality as microservices
- Proxy routes to old/new systems
@@ -39,11 +42,13 @@ Master microservices architecture patterns including service boundaries, inter-s
### 2. Communication Patterns
**Synchronous (Request/Response)**
- REST APIs
- gRPC
- GraphQL
**Asynchronous (Events/Messages)**
- Event streaming (Kafka)
- Message queues (RabbitMQ, SQS)
- Pub/Sub patterns
@@ -51,11 +56,13 @@ Master microservices architecture patterns including service boundaries, inter-s
### 3. Data Management
**Database Per Service**
- Each service owns its data
- No shared databases
- Loose coupling
**Saga Pattern**
- Distributed transactions
- Compensating actions
- Eventual consistency
@@ -63,14 +70,17 @@ Master microservices architecture patterns including service boundaries, inter-s
### 4. Resilience Patterns
**Circuit Breaker**
- Fail fast on repeated errors
- Prevent cascade failures
**Retry with Backoff**
- Transient fault handling
- Exponential backoff
**Bulkhead**
- Isolate resources
- Limit impact of failures

View File

@@ -33,12 +33,12 @@ Comprehensive guide to building projections and read models for event-sourced sy
### 2. Projection Types
| Type | Description | Use Case |
|------|-------------|----------|
| **Live** | Real-time from subscription | Current state queries |
| **Catchup** | Process historical events | Rebuilding read models |
| **Persistent** | Stores checkpoint | Resume after restart |
| **Inline** | Same transaction as write | Strong consistency |
| Type | Description | Use Case |
| -------------- | --------------------------- | ---------------------- |
| **Live** | Real-time from subscription | Current state queries |
| **Catchup** | Process historical events | Rebuilding read models |
| **Persistent** | Stores checkpoint | Resume after restart |
| **Inline** | Same transaction as write | Strong consistency |
## Templates
@@ -470,6 +470,7 @@ class CustomerActivityProjection(Projection):
## Best Practices
### Do's
- **Make projections idempotent** - Safe to replay
- **Use transactions** - For multi-table updates
- **Store checkpoints** - Resume after failures
@@ -477,6 +478,7 @@ class CustomerActivityProjection(Projection):
- **Plan for rebuilds** - Design for reconstruction
### Don'ts
- **Don't couple projections** - Each is independent
- **Don't skip error handling** - Log and alert on failures
- **Don't ignore ordering** - Events must be processed in order

View File

@@ -35,13 +35,13 @@ Choreography Orchestration
### 2. Saga Execution States
| State | Description |
|-------|-------------|
| **Started** | Saga initiated |
| **Pending** | Waiting for step completion |
| **Compensating** | Rolling back due to failure |
| **Completed** | All steps succeeded |
| **Failed** | Saga failed after compensation |
| State | Description |
| ---------------- | ------------------------------ |
| **Started** | Saga initiated |
| **Pending** | Waiting for step completion |
| **Compensating** | Rolling back due to failure |
| **Completed** | All steps succeeded |
| **Failed** | Saga failed after compensation |
## Templates
@@ -464,6 +464,7 @@ class TimeoutSagaOrchestrator(SagaOrchestrator):
## Best Practices
### Do's
- **Make steps idempotent** - Safe to retry
- **Design compensations carefully** - They must work
- **Use correlation IDs** - For tracing across services
@@ -471,6 +472,7 @@ class TimeoutSagaOrchestrator(SagaOrchestrator):
- **Log everything** - For debugging failures
### Don'ts
- **Don't assume instant completion** - Sagas take time
- **Don't skip compensation testing** - Most critical part
- **Don't couple services** - Use async messaging

View File

@@ -19,6 +19,7 @@ Comprehensive testing approaches for Temporal workflows using pytest, progressiv
## Testing Philosophy
**Recommended Approach** (Source: docs.temporal.io/develop/python/testing-suite):
- Write majority as integration tests
- Use pytest with async fixtures
- Time-skipping enables fast feedback (month-long workflows → seconds)
@@ -26,6 +27,7 @@ Comprehensive testing approaches for Temporal workflows using pytest, progressiv
- Validate determinism with replay testing
**Three Test Types**:
1. **Unit**: Workflows with time-skipping, activities with ActivityEnvironment
2. **Integration**: Workers with mocked activities
3. **End-to-end**: Full Temporal server with real activities (use sparingly)
@@ -35,9 +37,11 @@ Comprehensive testing approaches for Temporal workflows using pytest, progressiv
This skill provides detailed guidance through progressive disclosure. Load specific resources based on your testing needs:
### Unit Testing Resources
**File**: `resources/unit-testing.md`
**When to load**: Testing individual workflows or activities in isolation
**Contains**:
- WorkflowEnvironment with time-skipping
- ActivityEnvironment for activity testing
- Fast execution of long-running workflows
@@ -45,9 +49,11 @@ This skill provides detailed guidance through progressive disclosure. Load speci
- pytest fixtures and patterns
### Integration Testing Resources
**File**: `resources/integration-testing.md`
**When to load**: Testing workflows with mocked external dependencies
**Contains**:
- Activity mocking strategies
- Error injection patterns
- Multi-activity workflow testing
@@ -55,18 +61,22 @@ This skill provides detailed guidance through progressive disclosure. Load speci
- Coverage strategies
### Replay Testing Resources
**File**: `resources/replay-testing.md`
**When to load**: Validating determinism or deploying workflow changes
**Contains**:
- Determinism validation
- Production history replay
- CI/CD integration patterns
- Version compatibility testing
### Local Development Resources
**File**: `resources/local-setup.md`
**When to load**: Setting up development environment
**Contains**:
- Docker Compose configuration
- pytest setup and configuration
- Coverage tool integration
@@ -118,6 +128,7 @@ async def test_activity():
## Coverage Targets
**Recommended Coverage** (Source: docs.temporal.io best practices):
- **Workflows**: ≥80% logic coverage
- **Activities**: ≥80% logic coverage
- **Integration**: Critical paths with mocked activities
@@ -134,6 +145,7 @@ async def test_activity():
## How to Use Resources
**Load specific resource when needed**:
- "Show me unit testing patterns" → Load `resources/unit-testing.md`
- "How do I mock activities?" → Load `resources/integration-testing.md`
- "Setup local Temporal server" → Load `resources/local-setup.md`

View File

@@ -51,6 +51,7 @@ async def test_workflow_with_mocked_activity(workflow_env):
### Dynamic Mock Responses
**Scenario-Based Mocking**:
```python
@pytest.mark.asyncio
async def test_workflow_multiple_mock_scenarios(workflow_env):
@@ -106,6 +107,7 @@ async def test_workflow_multiple_mock_scenarios(workflow_env):
### Testing Transient Failures
**Retry Behavior**:
```python
@pytest.mark.asyncio
async def test_workflow_transient_errors(workflow_env):
@@ -154,6 +156,7 @@ async def test_workflow_transient_errors(workflow_env):
### Testing Non-Retryable Errors
**Business Validation Failures**:
```python
@pytest.mark.asyncio
async def test_workflow_non_retryable_error(workflow_env):

View File

@@ -519,6 +519,7 @@ async def test_workflow_with_breakpoint(workflow_env):
## Troubleshooting
**Issue: Temporal server not starting**
```bash
# Check logs
docker-compose logs temporal
@@ -529,12 +530,14 @@ docker-compose up -d
```
**Issue: Tests timing out**
```python
# Increase timeout in pytest.ini
asyncio_default_timeout = 30
```
**Issue: Port already in use**
```bash
# Find process using port 7233
lsof -i :7233

View File

@@ -7,12 +7,14 @@ Comprehensive guide for validating workflow determinism and ensuring safe code c
**Purpose**: Verify that workflow code changes are backward-compatible with existing workflow executions
**How it works**:
1. Temporal records every workflow decision as Event History
2. Replay testing re-executes workflow code against recorded history
3. If new code makes same decisions → deterministic (safe to deploy)
4. If decisions differ → non-deterministic (breaking change)
**Critical Use Cases**:
- Deploying workflow code changes to production
- Validating refactoring doesn't break running workflows
- CI/CD automated compatibility checks
@@ -78,6 +80,7 @@ async def test_replay_multiple_workflows():
### Common Non-Deterministic Patterns
**Problem: Random Number Generation**
```python
# ❌ Non-deterministic (breaks replay)
@workflow.defn
@@ -95,6 +98,7 @@ class GoodWorkflow:
```
**Problem: Current Time**
```python
# ❌ Non-deterministic
@workflow.defn
@@ -114,6 +118,7 @@ class GoodWorkflow:
```
**Problem: Direct External Calls**
```python
# ❌ Non-deterministic
@workflow.defn
@@ -432,6 +437,7 @@ class MigratedWorkflow:
## Common Replay Errors
**Non-Deterministic Error**:
```
WorkflowNonDeterministicError: Workflow command mismatch at position 5
Expected: ScheduleActivityTask(activity_id='activity-1')
@@ -441,6 +447,7 @@ Got: ScheduleActivityTask(activity_id='activity-2')
**Solution**: Code change altered workflow decision sequence
**Version Mismatch Error**:
```
WorkflowVersionError: Workflow version changed from 1 to 2 without using get_version()
```

View File

@@ -39,6 +39,7 @@ async def test_workflow_execution(workflow_env):
```
**Key Benefits**:
- `workflow.sleep(timedelta(days=30))` completes instantly
- Fast feedback loop (milliseconds vs hours)
- Deterministic test execution
@@ -46,6 +47,7 @@ async def test_workflow_execution(workflow_env):
### Time-Skipping Examples
**Sleep Advancement**:
```python
@pytest.mark.asyncio
async def test_workflow_with_delays(workflow_env):
@@ -72,6 +74,7 @@ async def test_workflow_with_delays(workflow_env):
```
**Manual Time Control**:
```python
@pytest.mark.asyncio
async def test_workflow_manual_time(workflow_env):
@@ -99,6 +102,7 @@ async def test_workflow_manual_time(workflow_env):
### Testing Workflow Logic
**Decision Testing**:
```python
@pytest.mark.asyncio
async def test_workflow_branching(workflow_env):
@@ -160,6 +164,7 @@ async def test_activity_basic():
### Testing Activity Context
**Heartbeat Testing**:
```python
async def test_activity_heartbeat():
"""Verify heartbeat calls"""
@@ -177,6 +182,7 @@ async def test_activity_heartbeat():
```
**Cancellation Testing**:
```python
async def test_activity_cancellation():
"""Test activity cancellation handling"""
@@ -199,6 +205,7 @@ async def test_activity_cancellation():
### Testing Error Handling
**Exception Propagation**:
```python
async def test_activity_error():
"""Test activity error handling"""
@@ -270,6 +277,7 @@ async def test_activity_parameterized(activity_env, input, expected):
## Common Patterns
**Testing Retry Logic**:
```python
@pytest.mark.asyncio
async def test_workflow_with_retries(workflow_env):

View File

@@ -30,12 +30,14 @@ Master workflow orchestration architecture with Temporal, covering fundamental d
## Critical Design Decision: Workflows vs Activities
**The Fundamental Rule** (Source: temporal.io/blog/workflow-engine-principles):
- **Workflows** = Orchestration logic and decision-making
- **Activities** = External interactions (APIs, databases, network calls)
### Workflows (Orchestration)
**Characteristics:**
- Contain business logic and coordination
- **MUST be deterministic** (same inputs → same outputs)
- **Cannot** perform direct external calls
@@ -43,6 +45,7 @@ Master workflow orchestration architecture with Temporal, covering fundamental d
- Can run for years despite infrastructure failures
**Example workflow tasks:**
- Decide which steps to execute
- Handle compensation logic
- Manage timeouts and retries
@@ -51,6 +54,7 @@ Master workflow orchestration architecture with Temporal, covering fundamental d
### Activities (External Interactions)
**Characteristics:**
- Handle all external system interactions
- Can be non-deterministic (API calls, DB writes)
- Include built-in timeouts and retry logic
@@ -58,6 +62,7 @@ Master workflow orchestration architecture with Temporal, covering fundamental d
- Short-lived (seconds to minutes typically)
**Example activity tasks:**
- Call payment gateway API
- Write to database
- Send emails or notifications
@@ -86,11 +91,13 @@ For each step:
```
**Example: Payment Workflow**
1. Reserve inventory (compensation: release inventory)
2. Charge payment (compensation: refund payment)
3. Fulfill order (compensation: cancel fulfillment)
**Critical Requirements:**
- Compensations must be idempotent
- Register compensation BEFORE executing step
- Run compensations in reverse order
@@ -101,17 +108,20 @@ For each step:
**Purpose**: Long-lived workflow representing single entity instance
**Pattern** (Source: docs.temporal.io/evaluate/use-cases-design-patterns):
- One workflow execution = one entity (cart, account, inventory item)
- Workflow persists for entity lifetime
- Receives signals for state changes
- Supports queries for current state
**Example Use Cases:**
- Shopping cart (add items, checkout, expiration)
- Bank account (deposits, withdrawals, balance checks)
- Product inventory (stock updates, reservations)
**Benefits:**
- Encapsulates entity behavior
- Guarantees consistency per entity
- Natural event sourcing
@@ -121,12 +131,14 @@ For each step:
**Purpose**: Execute multiple tasks in parallel, aggregate results
**Pattern:**
- Spawn child workflows or parallel activities
- Wait for all to complete
- Aggregate results
- Handle partial failures
**Scaling Rule** (Source: temporal.io/blog/workflow-engine-principles):
- Don't scale individual workflows
- For 1M tasks: spawn 1K child workflows × 1K tasks each
- Keep each workflow bounded
@@ -136,12 +148,14 @@ For each step:
**Purpose**: Wait for external event or human approval
**Pattern:**
- Workflow sends request and waits for signal
- External system processes asynchronously
- Sends signal to resume workflow
- Workflow continues with response
**Use Cases:**
- Human approval workflows
- Webhook callbacks
- Long-running external processes
@@ -151,6 +165,7 @@ For each step:
### Automatic State Preservation
**How Temporal Works** (Source: docs.temporal.io/workflows):
- Complete program state preserved automatically
- Event History records every command and event
- Seamless recovery from crashes
@@ -159,10 +174,12 @@ For each step:
### Determinism Constraints
**Workflows Execute as State Machines**:
- Replay behavior must be consistent
- Same inputs → identical outputs every time
**Prohibited in Workflows** (Source: docs.temporal.io/workflows):
- ❌ Threading, locks, synchronization primitives
- ❌ Random number generation (`random()`)
- ❌ Global state or static variables
@@ -171,6 +188,7 @@ For each step:
- ❌ Non-deterministic libraries
**Allowed in Workflows**:
-`workflow.now()` (deterministic time)
-`workflow.random()` (deterministic random)
- ✅ Pure functions and calculations
@@ -181,6 +199,7 @@ For each step:
**Challenge**: Changing workflow code while old executions still running
**Solutions**:
1. **Versioning API**: Use `workflow.get_version()` for safe changes
2. **New Workflow Type**: Create new workflow, route new executions to it
3. **Backward Compatibility**: Ensure old events replay correctly
@@ -192,12 +211,14 @@ For each step:
**Default Behavior**: Temporal retries activities forever
**Configure Retry**:
- Initial retry interval
- Backoff coefficient (exponential backoff)
- Maximum interval (cap retry delay)
- Maximum attempts (eventually fail)
**Non-Retryable Errors**:
- Invalid input (validation failures)
- Business rule violations
- Permanent failures (resource not found)
@@ -205,11 +226,13 @@ For each step:
### Idempotency Requirements
**Why Critical** (Source: docs.temporal.io/activities):
- Activities may execute multiple times
- Network failures trigger retries
- Duplicate execution must be safe
**Implementation Strategies**:
- Idempotency keys (deduplication)
- Check-then-act with unique constraints
- Upsert operations instead of insert
@@ -220,6 +243,7 @@ For each step:
**Purpose**: Detect stalled long-running activities
**Pattern**:
- Activity sends periodic heartbeat
- Includes progress information
- Timeout if no heartbeat received
@@ -245,12 +269,14 @@ For each step:
### Common Pitfalls
**Workflow Violations**:
- Using `datetime.now()` instead of `workflow.now()`
- Threading or async operations in workflow code
- Calling external APIs directly from workflow
- Non-deterministic logic in workflows
**Activity Mistakes**:
- Non-idempotent operations (can't handle retries)
- Missing timeouts (activities run forever)
- No error classification (retry validation errors)
@@ -259,12 +285,14 @@ For each step:
### Operational Considerations
**Monitoring**:
- Workflow execution duration
- Activity failure rates
- Retry attempts and backoff
- Pending workflow counts
**Scalability**:
- Horizontal scaling with workers
- Task queue partitioning
- Child workflow decomposition
@@ -273,12 +301,14 @@ For each step:
## Additional Resources
**Official Documentation**:
- Temporal Core Concepts: docs.temporal.io/workflows
- Workflow Patterns: docs.temporal.io/evaluate/use-cases-design-patterns
- Best Practices: docs.temporal.io/develop/best-practices
- Saga Pattern: temporal.io/blog/saga-pattern-made-easy
**Key Principles**:
1. Workflows = orchestration, Activities = external calls
2. Determinism is non-negotiable for workflows
3. Idempotency is critical for activities