mirror of
https://github.com/wshobson/agents.git
synced 2026-03-18 09:37:15 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
```
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user