micro-clean-gen


Namemicro-clean-gen JSON
Version 1.0.0 PyPI version JSON
download
home_pagehttps://github.com/DotNetAge/micro-gen
Summary基于整洁架构的事件驱动微服务代码生成器
upload_time2025-08-29 07:54:00
maintainerNone
docs_urlNone
authorRay
requires_python>=3.8
licenseMIT
keywords microservice clean-architecture code-generator event-driven ddd
VCS
bugtrack_url
requirements pyyaml jinja2 click colorama pathlib2 jsonschema loguru
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 🐍 Python版整洁架构事件驱动微服务生成器

> **无需Go环境,纯Python一键生成** 整洁架构 + 事件溯源 + CQRS + Projection 完整项目

## 🎯 核心特性

| 特性         | 描述                           |
| ------------ | ------------------------------ |
| **零依赖**   | 只需Python3,无需Go环境        |
| **整洁架构** | 严格遵循Clean Architecture原则 |
| **事件溯源** | 完整的事件存储和重播机制       |
| **CQRS**     | 读写分离,高性能查询           |
| **投影系统** | 毫秒级查询响应                 |
| **一键启动** | 15秒内生成完整项目             |

## 🚀 快速开始

### 1. 生成图片管理系统示例

```bash
python3 python-generator.py --config examples/clean-arch-go-config.yaml --project image-system --quick-start
```

### 2. 15秒启动完整系统

```bash
cd image-system
./scripts/start.sh

# 访问服务
API: http://localhost:8080
NATS监控: http://localhost:8222
```

## 📁 生成的项目结构

```
project-name/
├── cmd/                    # 应用入口
│   ├── api/               # HTTP API服务
│   ├── consumer/          # 事件消费者
│   ├── projection/        # 投影构建器
│   └── migration/         # 数据库迁移
├── internal/              # 核心业务逻辑
│   ├── domain/            # 领域层
│   │   ├── aggregate/     # 聚合根
│   │   ├── event/         # 领域事件
│   │   ├── repository/    # 仓储接口
│   │   └── projection/    # 投影接口
│   ├── usecase/           # 用例层
│   │   ├── command/       # 写用例
│   │   ├── query/         # 读用例
│   │   └── event/         # 事件处理
│   ├── adapter/           # 适配器层
│   │   ├── inbound/       # 输入适配器
│   │   └── outbound/      # 输出适配器
│   ├── infrastructure/    # 基础设施层
│   │   ├── config/        # 配置管理
│   │   ├── bootstrap/     # 服务引导程序
│   │   ├── database/      # 数据库连接
│   │   ├── eventstore/    # 事件存储
│   │   └── container/     # 依赖注入容器
├── configs/               # 配置文件
│   ├── app.yaml          # 应用配置
│   └── .env.example      # 环境变量模板
├── migrations/            # 数据库迁移
├── scripts/               # 开发脚本
└── docs/                  # 项目文档
```

## 🏗️ 架构层次

### 领域层 (Domain Layer)
- **聚合根**: 核心业务逻辑和状态
- **领域事件**: 业务状态变化的记录
- **仓储接口**: 数据持久化抽象

### 用例层 (Use Case Layer)
- **命令用例**: 处理写操作
- **查询用例**: 处理读操作
- **事件处理**: 响应领域事件

### 适配器层 (Adapter Layer)
- **输入适配器**: HTTP API, gRPC, CLI
- **输出适配器**: 数据库, 消息队列, 缓存

### 基础设施层 (Infrastructure Layer)
- **事件存储**: PostgreSQL + NATS
- **投影存储**: PostgreSQL + Redis
- **缓存层**: Redis多级缓存

## 🎯 事件溯源实现

### 事件存储
```go
// 事件存储接口
type EventStore interface {
    Save(ctx context.Context, aggregateID string, events []interface{}, version int) error
    Load(ctx context.Context, aggregateID string) ([]interface{}, error)
    Publish(ctx context.Context, event interface{}) error
    
    // 快照支持
    SaveSnapshot(ctx context.Context, aggregateID string, snapshot interface{}, version int) error
    LoadSnapshot(ctx context.Context, aggregateID string) (interface{}, int, error)
    GetSnapshotVersion(ctx context.Context, aggregateID string) (int, error)
}

// 快照接口
type Snapshot interface {
    GetAggregateID() string
    GetVersion() int
    GetSnapshotData() interface{}
}

// 聚合根快照基类
type AggregateSnapshot struct {
    AggregateID string
    Version     int
    Data        interface{}
}

func (s *AggregateSnapshot) GetAggregateID() string {
    return s.AggregateID
}

func (s *AggregateSnapshot) GetVersion() int {
    return s.Version
}

func (s *AggregateSnapshot) GetSnapshotData() interface{} {
    return s.Data
}
```

### 投影系统
```go
// 投影构建器
type Projection interface {
    Project(ctx context.Context, event interface{}) error
    Get(ctx context.Context, id string) (interface{}, error)
}
```

## 📊 性能基准

| 操作类型 | 响应时间      | 并发能力   |
| -------- | ------------- | ---------- |
| 创建聚合 | < 50ms        | 1000+ TPS  |
| 查询投影 | < 5ms         | 10000+ QPS |
| 事件重播 | < 1s/1000事件 | 可并行     |
| 投影更新 | < 100ms       | 实时更新   |

## 🚀 Bootstrap系统

### 服务引导程序
```go
// 使用Bootstrap启动应用
func main() {
    bootstrap.Run()
}
```

### 配置管理
```go
// 使用Viper加载配置
cfg, err := config.LoadConfig()
```

### 依赖注入容器
```go
// 容器管理所有依赖
container := container.NewContainer(cfg)
container.InitInfrastructure(ctx)
container.InitRepositories()
container.InitUseCases()
container.InitHTTPServer()
```

### 配置方式

#### 1. 配置文件 (configs/app.yaml)
```yaml
app:
  name: my-service
  version: 1.0.0
  environment: development
  debug: true

database:
  host: localhost
  port: 5432
  user: user
  password: password
  dbname: mydb
```

#### 2. 环境变量
```bash
# 数据库配置
export DB_HOST=localhost
export DB_PORT=5432
export DB_USER=user
export DB_PASSWORD=password

# 启动应用
./scripts/start.sh
```

#### 3. .env文件
```bash
# 复制环境变量模板
cp configs/.env.example configs/.env
# 编辑配置文件
vim configs/.env
```

## 🛠️ 开发工具

### 一键启动
```bash
# 开发环境
./scripts/start.sh

# 生产环境
./scripts/build.sh
docker-compose up -d
```

### 数据库迁移
```bash
# 自动迁移
go run cmd/migration/main.go

# 手动迁移
psql -h localhost -U user -d image_system -f migrations/001_create_events.up.sql
```

### 测试命令
```bash
# 单元测试
go test ./...

# 集成测试
./scripts/test.sh

# 性能测试
./scripts/benchmark.sh
```

## 🎨 DSL配置指南

### 配置文件结构详解

Python生成器使用YAML格式的DSL(领域特定语言)来定义整个微服务的架构。配置文件支持以下顶级配置项:

#### 📋 项目配置 (project)
定义项目的基本信息:

```yaml
project:
  name: my-service                    # 项目名称(必填)- 用于包名、模块名
  description: 我的微服务              # 项目描述(可选)- 用于README文档
  version: 1.0.0                    # 版本号(可选)- 默认为1.0.0
  author: Your Name                 # 作者信息(可选)
  go_version: 1.21                  # Go版本(可选)- 默认为1.21
```

#### 🏗️ 聚合根配置 (aggregates)
定义业务聚合根,每个聚合根对应一个核心业务实体:

```yaml
aggregates:
  - name: User                      # 聚合根名称(必填)- 首字母大写
    description: 用户聚合根           # 描述(可选)
    fields:                         # 聚合根字段定义
      - name: username              # 字段名(必填)
        type: string                # Go类型(必填)- string/int/float64/bool/time.Time
        json: username              # JSON标签(可选)- 默认为字段名小写
        gorm: uniqueIndex           # GORM标签(可选)- 支持所有GORM标签
        validate: required,min=3    # 验证标签(可选)- 支持go-playground/validator
        description: 用户名           # 字段描述(可选)
      
      - name: email
        type: string
        json: email
        validate: required,email
        gorm: uniqueIndex
        
      - name: age
        type: int
        json: age
        validate: min=0,max=150
        
      - name: active
        type: bool
        json: active
        default: true                 # 默认值(可选)
```

#### ⚡ 事件定义 (events)
每个聚合根可以定义多个领域事件:

```yaml
    events:
      - name: UserCreated            # 事件名称(必填)- 必须以聚合根名开头
        description: 用户创建事件      # 事件描述(可选)
        fields:                      # 事件字段(可选)
          - name: UserID
            type: string
            json: user_id
            description: 用户ID
            
          - name: Username
            type: string
            json: username
            
      - name: UserUpdated
        description: 用户更新事件
        fields:
          - name: UserID
            type: string
            json: user_id
            
          - name: UpdatedFields
            type: map[string]interface{}  # 支持复杂类型
            json: updated_fields
            
      - name: UserDeleted
        description: 用户删除事件
        fields:
          - name: UserID
            type: string
            json: user_id
            
          - name: DeletedAt
            type: time.Time
            json: deleted_at
```

#### 📊 投影配置 (projections)
定义事件投影模型(可选配置):

```yaml
projections:
  - name: UserProjection            # 投影名称(必填)
    aggregate: User                 # 关联的聚合根(必填)
    description: 用户查询投影        # 描述(可选)
    fields:                         # 投影字段定义
      - name: ID
        type: string
        gorm: primaryKey
        
      - name: Username
        type: string
        gorm: index
        
      - name: Email
        type: string
        gorm: uniqueIndex
        
      - name: Active
        type: bool
        gorm: index
```

#### 🔧 基础设施配置 (infrastructure)
定义基础设施依赖:

```yaml
infrastructure:
  database:                       # 数据库配置
    type: postgresql              # 支持postgresql/mysql/sqlite
    host: localhost
    port: 5432
    database: myservice
    username: user
    password: password
    
  cache:                         # 缓存配置
    type: redis                  # 支持redis/memcached
    host: localhost
    port: 6379
    
  message_queue:               # 消息队列
    type: nats                 # 支持nats/rabbitmq/kafka
    host: localhost
    port: 4222
    
  monitoring:                  # 监控配置
    metrics: true              # 启用Prometheus指标
    tracing: true              # 启用分布式追踪
    logging: zap               # 日志库选择
```

#### 🌐 API配置 (api)
定义API接口:

```yaml
api:
  http:                        # HTTP配置
    enabled: true
    port: 8080
    prefix: /api/v1
    
  grpc:                       # gRPC配置
    enabled: true
    port: 50051
    reflection: true          # 启用服务反射
    
  cors:                      # CORS配置
    enabled: true
    origins: ["*"]
    methods: ["GET", "POST", "PUT", "DELETE"]
    headers: ["Content-Type", "Authorization"]
```

#### 🔗 会话管理 (session)
分布式会话管理配置,用于长时任务和Saga事务:

```yaml
session:
  enabled: true              # 启用会话管理
  
  saga:                      # Saga配置
    enabled: true
    timeout: 30m             # Saga超时时间
    compensation: true       # 启用补偿机制
    
  context:                   # 会话上下文
    storage: redis          # 存储后端: redis/postgresql
    ttl: 24h                # 会话TTL
    compression: true       # 启用压缩
    
  orchestration:            # 编排配置
    pattern: choreography   # 编排模式: choreography/orchestration
    coordinator: enabled    # 启用协调器(仅orchestration模式)
    
  checkpoint:              # 检查点机制
    enabled: true
    interval: 30s           # 自动检查点间隔
    storage: postgresql     # 检查点存储
    
  recovery:                # 故障恢复
    enabled: true
    strategy: retry         # 恢复策略: retry/rollback/compensate
    max_retries: 3        # 最大重试次数
    backoff: exponential  # 退避策略
```

#### 🔄 长时任务 (long_running)
长时任务和批处理配置:

```yaml
long_running:
  enabled: true
  
  tasks:
    - name: ImageProcessingTask
      type: batch             # 任务类型: batch/streaming
      timeout: 2h
      parallelism: 5         # 并行度
      
      stages:               # 处理阶段
        - name: Download
          timeout: 10m
          retry_policy: 3
          
        - name: Process
          timeout: 1h
          checkpoint: true   # 启用检查点
          
        - name: Upload
          timeout: 30m
          retry_policy: 5
          
      context:              # 会话上下文
        required_fields:
          - user_id
          - image_urls
          - processing_config
        
        distributed_lock: true    # 分布式锁
        state_machine: true      # 状态机
        
      compensation:         # 补偿机制
        enabled: true
        rollback_steps:
          - DeleteTempFiles
          - RevertDatabase
          - SendNotification
```

### 完整配置示例

```yaml
# 完整项目配置示例
project:
  name: ecommerce-order-service
  description: 电商订单服务 - 支持订单创建、支付、发货等完整生命周期
  version: 2.1.0
  author: 架构团队
  go_version: 1.21

aggregates:
  - name: Order
    description: 订单聚合根
    fields:
      - name: OrderNumber
        type: string
        json: order_number
        validate: required
        gorm: uniqueIndex
        description: 订单号
        
      - name: CustomerID
        type: string
        json: customer_id
        validate: required,uuid
        gorm: index
        description: 客户ID
        
      - name: TotalAmount
        type: float64
        json: total_amount
        validate: required,min=0
        description: 订单总金额
        
      - name: Status
        type: string
        json: status
        validate: required,oneof=pending paid shipped delivered cancelled
        gorm: index
        default: pending
        description: 订单状态
        
      - name: ShippingAddress
        type: string
        json: shipping_address
        validate: required
        description: 收货地址
        
    events:
      - name: OrderCreated
        description: 订单创建事件
        fields:
          - name: OrderID
            type: string
            json: order_id
            validate: required,uuid
            
          - name: Items
            type: "[]OrderItem"  # 支持自定义类型
            json: items
            
      - name: OrderPaid
        description: 订单支付事件
        fields:
          - name: OrderID
            type: string
            json: order_id
            
          - name: PaymentID
            type: string
            json: payment_id
            
          - name: PaidAt
            type: time.Time
            json: paid_at
            
      - name: OrderShipped
        description: 订单发货事件
        fields:
          - name: OrderID
            type: string
            json: order_id
            
          - name: TrackingNumber
            type: string
            json: tracking_number
            
      - name: OrderDelivered
        description: 订单送达事件
        fields:
          - name: OrderID
            type: string
            json: order_id
            
          - name: DeliveredAt
            type: time.Time
            json: delivered_at

projections:
  - name: OrderSummaryProjection
    aggregate: Order
    description: 订单摘要投影 - 用于查询订单列表
    fields:
      - name: ID
        type: string
        gorm: primaryKey
        
      - name: OrderNumber
        type: string
        gorm: uniqueIndex
        
      - name: CustomerID
        type: string
        gorm: index
        
      - name: TotalAmount
        type: float64
        
      - name: Status
        type: string
        gorm: index
        
      - name: CreatedAt
        type: time.Time
        gorm: index

infrastructure:
  database:
    type: postgresql
    host: localhost
    port: 5432
    database: ecommerce
    username: ecommerce_user
    password: secure_password
    
  cache:
    type: redis
    host: localhost
    port: 6379
    
  message_queue:
    type: nats
    host: localhost
    port: 4222
    
  monitoring:
    metrics: true
    tracing: true
    logging: zap

api:
  http:
    enabled: true
    port: 8080
    prefix: /api/v2
    
  grpc:
    enabled: true
    port: 50051
    reflection: true
    
  cors:
    enabled: true
    origins: ["https://frontend.com", "https://admin.com"]
    methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
    headers: ["Content-Type", "Authorization", "X-Requested-With"]

session:
  enabled: true
  
  saga:
    enabled: true
    timeout: 30m
    compensation: true
    
  context:
    storage: redis
    ttl: 24h
    compression: true
    
  orchestration:
    pattern: choreography
    coordinator: enabled
    
  checkpoint:
    enabled: true
    interval: 30s
    storage: postgresql
    
  recovery:
    enabled: true
    strategy: retry
    max_retries: 3
    backoff: exponential

long_running:
  enabled: true
  
  tasks:
    - name: OrderFulfillmentTask
      type: batch
      timeout: 4h
      parallelism: 3
      
      stages:
        - name: InventoryCheck
          timeout: 5m
          retry_policy: 3
          
        - name: PaymentProcessing
          timeout: 15m
          checkpoint: true
          
        - name: ShippingArrangement
          timeout: 1h
          retry_policy: 2
          
        - name: Notification
          timeout: 5m
          
      context:
        required_fields:
          - order_id
          - customer_id
          - payment_method
          - shipping_address
        
        distributed_lock: true
        state_machine: true
        
      compensation:
        enabled: true
        rollback_steps:
          - ReleaseInventory
          - RefundPayment
          - CancelShipping
          - SendCancellationNotification
```

### 生成项目

使用配置文件生成项目:

```bash
# 基础用法
python3 clean-arch-generator.py --config my-service.yaml

# 指定输出目录
python3 clean-arch-generator.py --config my-service.yaml --output ./projects/

# 使用自定义项目名
python3 clean-arch-generator.py --config my-service.yaml --project custom-name
```

### 支持的Go类型映射

| DSL类型                | Go类型                 | 数据库类型   | 描述       |
| ---------------------- | ---------------------- | ------------ | ---------- |
| string                 | string                 | VARCHAR(255) | 字符串     |
| int                    | int                    | INTEGER      | 整数       |
| int64                  | int64                  | BIGINT       | 大整数     |
| float64                | float64                | DECIMAL      | 浮点数     |
| bool                   | bool                   | BOOLEAN      | 布尔值     |
| time.Time              | time.Time              | TIMESTAMP    | 时间戳     |
| uuid.UUID              | uuid.UUID              | UUID         | UUID       |
| json.RawMessage        | json.RawMessage        | JSONB        | JSON数据   |
| []string               | []string               | TEXT[]       | 字符串数组 |
| map[string]interface{} | map[string]interface{} | JSONB        | JSON对象   |

## 🔧 技术栈

### 核心依赖
- **Go**: 1.21+
- **PostgreSQL**: 15+ (事件存储)
- **Redis**: 7+ (缓存和投影)
- **NATS**: 2+ (消息队列)

### 开发工具
- **Docker**: 容器化部署
- **Docker Compose**: 本地开发
- **Make**: 构建工具
- **Air**: 热重载

## 🎯 会话管理架构

### 分布式会话设计

```
┌─────────────────────────────────────────────────────────────┐
│                    Session Management Layer                 │
├─────────────────┬─────────────────┬───────────────────────────┤
│   Saga Manager  │ Context Manager │  Checkpoint Manager       │
│                 │                 │                           │
│ ┌─────────────┐ │ ┌─────────────┐ │ ┌───────────────────────┐ │
│ │ Coordinator │ │ │  Session    │ │ │   State Machine     │ │
│ │   / Choreo  │ │ │  Context    │ │ │   Recovery Engine   │ │
│ └─────────────┘ │ └─────────────┘ │ └───────────────────────┘ │
└─────────────────┴─────────────────┴───────────────────────────┘
                              │
┌─────────────────────────────────────────────────────────────┐
│                    Storage Layer                           │
├─────────────────┬─────────────────┬───────────────────────────┤
│     Redis       │   PostgreSQL    │     Event Store          │
│  (Session TTL)  │ (Checkpoint)    │   (Event Log)            │
└─────────────────┴─────────────────┴───────────────────────────┘
```

### 会话上下文结构

```go
type SessionContext struct {
    SessionID    string                 `json:"session_id"`
    SagaID       string                 `json:"saga_id"`
    WorkflowID   string                 `json:"workflow_id"`
    
    // 执行状态
    CurrentStage string                 `json:"current_stage"`
    StageIndex   int                    `json:"stage_index"`
    Status       SessionStatus          `json:"status"`
    
    // 业务上下文
    Payload      map[string]interface{} `json:"payload"`
    Metadata     map[string]string      `json:"metadata"`
    
    // 时间控制
    CreatedAt    time.Time              `json:"created_at"`
    UpdatedAt    time.Time              `json:"updated_at"`
    ExpiresAt    time.Time              `json:"expires_at"`
    
    // 故障恢复
    RetryCount   int                    `json:"retry_count"`
    LastError    string                 `json:"last_error"`
    
    // 分布式锁
    LockToken    string                 `json:"lock_token"`
    LockedBy     string                 `json:"locked_by"`
    LockExpiry   time.Time              `json:"lock_expiry"`
}
```

### 会话生命周期管理

```go
type SessionManager interface {
    // 会话创建
    CreateSession(ctx context.Context, workflowID string, payload map[string]interface{}) (*SessionContext, error)
    
    // 状态更新
    UpdateStage(ctx context.Context, sessionID string, stage string, data map[string]interface{}) error
    
    // 检查点
    SaveCheckpoint(ctx context.Context, sessionID string, stageIndex int) error
    
    // 故障恢复
    RecoverSession(ctx context.Context, sessionID string) (*SessionContext, error)
    
    // 分布式锁
    AcquireLock(ctx context.Context, sessionID string, instanceID string) (bool, error)
    ReleaseLock(ctx context.Context, sessionID string, lockToken string) error
    
    // 补偿机制
    Compensate(ctx context.Context, sessionID string, steps []string) error
}
```

### 实际使用示例

#### 1. 启动长时任务会话
```go
// 创建订单履约会话
session, err := sessionManager.CreateSession(ctx, "order-fulfillment", map[string]interface{}{
    "order_id":      order.ID,
    "customer_id":   order.CustomerID,
    "payment_method": order.PaymentMethod,
    "shipping_address": order.ShippingAddress,
})
```

#### 2. 阶段执行与检查点
```go
// 执行库存检查阶段
func (s *OrderFulfillmentService) executeInventoryCheck(ctx context.Context, sessionID string) error {
    // 获取会话上下文
    session, err := s.sessionManager.GetSession(ctx, sessionID)
    if err != nil {
        return fmt.Errorf("failed to get session: %w", err)
    }
    
    // 执行业务逻辑
    if err := s.inventoryService.CheckAvailability(ctx, session.Payload["order_id"]); err != nil {
        // 保存失败状态
        s.sessionManager.UpdateStage(ctx, sessionID, "inventory_check_failed", map[string]interface{}{
            "error": err.Error(),
        })
        return err
    }
    
    // 保存检查点
    return s.sessionManager.SaveCheckpoint(ctx, sessionID, 1)
}
```

#### 3. 故障恢复
```go
// 服务重启后恢复会话
func (s *OrderFulfillmentService) recoverSessions(ctx context.Context) error {
    // 获取所有未完成的会话
    sessions, err := s.sessionManager.GetActiveSessions(ctx)
    if err != nil {
        return err
    }
    
    for _, session := range sessions {
        // 检查分布式锁
        locked, err := s.sessionManager.AcquireLock(ctx, session.SessionID, s.instanceID)
        if err != nil || !locked {
            continue // 其他实例正在处理
        }
        
        // 恢复执行
        go s.resumeWorkflow(ctx, session)
    }
    
    return nil
}
```

### 会话存储策略

#### Redis存储(高性能)
```yaml
session:
  context:
    storage: redis
    ttl: 24h
    compression: true
    key_prefix: "session:"
    cluster_mode: true
```

#### PostgreSQL存储(持久化)
```yaml
session:
  context:
    storage: postgresql
    ttl: 7d
    table_name: "session_contexts"
    cleanup_interval: 1h
```

### 故障恢复策略

#### 1. 重试策略(Retry)
```go
// 指数退避重试
backoff := &ExponentialBackoff{
    InitialInterval: time.Second,
    MaxInterval:     time.Minute,
    Multiplier:      2.0,
    MaxRetries:      3,
}

for i := 0; i < backoff.MaxRetries; i++ {
    err := executeStage(ctx, sessionID)
    if err == nil {
        break
    }
    
    if i < backoff.MaxRetries-1 {
        time.Sleep(backoff.NextInterval(i))
    }
}
```

#### 2. 补偿策略(Compensate)
```go
// Saga补偿机制
func (s *OrderFulfillmentService) compensate(ctx context.Context, sessionID string) error {
    session, _ := s.sessionManager.GetSession(ctx, sessionID)
    
    // 逆序执行补偿步骤
    for i := len(session.CompletedStages) - 1; i >= 0; i-- {
        stage := session.CompletedStages[i]
        
        switch stage.Name {
        case "inventory_reserved":
            s.inventoryService.ReleaseReservation(ctx, session.Payload["order_id"])
        case "payment_processed":
            s.paymentService.Refund(ctx, session.Payload["payment_id"])
        case "shipping_arranged":
            s.shippingService.CancelShipment(ctx, session.Payload["shipment_id"])
        }
    }
    
    return s.sessionManager.Compensate(ctx, sessionID, []string{"all"})
}
```

## 📈 扩展能力

## 🎓 学习资源

### 文档
- [整洁架构指南](docs/architecture.md)
- [API文档](docs/api.md)
- [部署指南](docs/deployment.md)

### 示例项目
- [图片管理系统](examples/clean-arch-go-config.yaml)
- [订单系统](examples/order-system.yaml)
- [用户管理系统](examples/user-system.yaml)

## 🤝 贡献指南

1. Fork项目
2. 创建功能分支
3. 提交Pull Request
4. 通过代码审查

## 📄 许可证

MIT License - 自由使用,欢迎贡献!

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/DotNetAge/micro-gen",
    "name": "micro-clean-gen",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "Ray <ray@rayainfo.cn>",
    "keywords": "microservice, clean-architecture, code-generator, event-driven, ddd",
    "author": "Ray",
    "author_email": "Ray <ray@rayainfo.cn>",
    "download_url": "https://files.pythonhosted.org/packages/ae/20/63dbc755c49e83d9e7c24f7aa0af5ca206c008bde3857e1e831146dc0e47/micro_clean_gen-1.0.0.tar.gz",
    "platform": null,
    "description": "# \ud83d\udc0d Python\u7248\u6574\u6d01\u67b6\u6784\u4e8b\u4ef6\u9a71\u52a8\u5fae\u670d\u52a1\u751f\u6210\u5668\n\n> **\u65e0\u9700Go\u73af\u5883\uff0c\u7eafPython\u4e00\u952e\u751f\u6210** \u6574\u6d01\u67b6\u6784 + \u4e8b\u4ef6\u6eaf\u6e90 + CQRS + Projection \u5b8c\u6574\u9879\u76ee\n\n## \ud83c\udfaf \u6838\u5fc3\u7279\u6027\n\n| \u7279\u6027         | \u63cf\u8ff0                           |\n| ------------ | ------------------------------ |\n| **\u96f6\u4f9d\u8d56**   | \u53ea\u9700Python3\uff0c\u65e0\u9700Go\u73af\u5883        |\n| **\u6574\u6d01\u67b6\u6784** | \u4e25\u683c\u9075\u5faaClean Architecture\u539f\u5219 |\n| **\u4e8b\u4ef6\u6eaf\u6e90** | \u5b8c\u6574\u7684\u4e8b\u4ef6\u5b58\u50a8\u548c\u91cd\u64ad\u673a\u5236       |\n| **CQRS**     | \u8bfb\u5199\u5206\u79bb\uff0c\u9ad8\u6027\u80fd\u67e5\u8be2           |\n| **\u6295\u5f71\u7cfb\u7edf** | \u6beb\u79d2\u7ea7\u67e5\u8be2\u54cd\u5e94                 |\n| **\u4e00\u952e\u542f\u52a8** | 15\u79d2\u5185\u751f\u6210\u5b8c\u6574\u9879\u76ee             |\n\n## \ud83d\ude80 \u5feb\u901f\u5f00\u59cb\n\n### 1. \u751f\u6210\u56fe\u7247\u7ba1\u7406\u7cfb\u7edf\u793a\u4f8b\n\n```bash\npython3 python-generator.py --config examples/clean-arch-go-config.yaml --project image-system --quick-start\n```\n\n### 2. 15\u79d2\u542f\u52a8\u5b8c\u6574\u7cfb\u7edf\n\n```bash\ncd image-system\n./scripts/start.sh\n\n# \u8bbf\u95ee\u670d\u52a1\nAPI: http://localhost:8080\nNATS\u76d1\u63a7: http://localhost:8222\n```\n\n## \ud83d\udcc1 \u751f\u6210\u7684\u9879\u76ee\u7ed3\u6784\n\n```\nproject-name/\n\u251c\u2500\u2500 cmd/                    # \u5e94\u7528\u5165\u53e3\n\u2502   \u251c\u2500\u2500 api/               # HTTP API\u670d\u52a1\n\u2502   \u251c\u2500\u2500 consumer/          # \u4e8b\u4ef6\u6d88\u8d39\u8005\n\u2502   \u251c\u2500\u2500 projection/        # \u6295\u5f71\u6784\u5efa\u5668\n\u2502   \u2514\u2500\u2500 migration/         # \u6570\u636e\u5e93\u8fc1\u79fb\n\u251c\u2500\u2500 internal/              # \u6838\u5fc3\u4e1a\u52a1\u903b\u8f91\n\u2502   \u251c\u2500\u2500 domain/            # \u9886\u57df\u5c42\n\u2502   \u2502   \u251c\u2500\u2500 aggregate/     # \u805a\u5408\u6839\n\u2502   \u2502   \u251c\u2500\u2500 event/         # \u9886\u57df\u4e8b\u4ef6\n\u2502   \u2502   \u251c\u2500\u2500 repository/    # \u4ed3\u50a8\u63a5\u53e3\n\u2502   \u2502   \u2514\u2500\u2500 projection/    # \u6295\u5f71\u63a5\u53e3\n\u2502   \u251c\u2500\u2500 usecase/           # \u7528\u4f8b\u5c42\n\u2502   \u2502   \u251c\u2500\u2500 command/       # \u5199\u7528\u4f8b\n\u2502   \u2502   \u251c\u2500\u2500 query/         # \u8bfb\u7528\u4f8b\n\u2502   \u2502   \u2514\u2500\u2500 event/         # \u4e8b\u4ef6\u5904\u7406\n\u2502   \u251c\u2500\u2500 adapter/           # \u9002\u914d\u5668\u5c42\n\u2502   \u2502   \u251c\u2500\u2500 inbound/       # \u8f93\u5165\u9002\u914d\u5668\n\u2502   \u2502   \u2514\u2500\u2500 outbound/      # \u8f93\u51fa\u9002\u914d\u5668\n\u2502   \u251c\u2500\u2500 infrastructure/    # \u57fa\u7840\u8bbe\u65bd\u5c42\n\u2502   \u2502   \u251c\u2500\u2500 config/        # \u914d\u7f6e\u7ba1\u7406\n\u2502   \u2502   \u251c\u2500\u2500 bootstrap/     # \u670d\u52a1\u5f15\u5bfc\u7a0b\u5e8f\n\u2502   \u2502   \u251c\u2500\u2500 database/      # \u6570\u636e\u5e93\u8fde\u63a5\n\u2502   \u2502   \u251c\u2500\u2500 eventstore/    # \u4e8b\u4ef6\u5b58\u50a8\n\u2502   \u2502   \u2514\u2500\u2500 container/     # \u4f9d\u8d56\u6ce8\u5165\u5bb9\u5668\n\u251c\u2500\u2500 configs/               # \u914d\u7f6e\u6587\u4ef6\n\u2502   \u251c\u2500\u2500 app.yaml          # \u5e94\u7528\u914d\u7f6e\n\u2502   \u2514\u2500\u2500 .env.example      # \u73af\u5883\u53d8\u91cf\u6a21\u677f\n\u251c\u2500\u2500 migrations/            # \u6570\u636e\u5e93\u8fc1\u79fb\n\u251c\u2500\u2500 scripts/               # \u5f00\u53d1\u811a\u672c\n\u2514\u2500\u2500 docs/                  # \u9879\u76ee\u6587\u6863\n```\n\n## \ud83c\udfd7\ufe0f \u67b6\u6784\u5c42\u6b21\n\n### \u9886\u57df\u5c42 (Domain Layer)\n- **\u805a\u5408\u6839**: \u6838\u5fc3\u4e1a\u52a1\u903b\u8f91\u548c\u72b6\u6001\n- **\u9886\u57df\u4e8b\u4ef6**: \u4e1a\u52a1\u72b6\u6001\u53d8\u5316\u7684\u8bb0\u5f55\n- **\u4ed3\u50a8\u63a5\u53e3**: \u6570\u636e\u6301\u4e45\u5316\u62bd\u8c61\n\n### \u7528\u4f8b\u5c42 (Use Case Layer)\n- **\u547d\u4ee4\u7528\u4f8b**: \u5904\u7406\u5199\u64cd\u4f5c\n- **\u67e5\u8be2\u7528\u4f8b**: \u5904\u7406\u8bfb\u64cd\u4f5c\n- **\u4e8b\u4ef6\u5904\u7406**: \u54cd\u5e94\u9886\u57df\u4e8b\u4ef6\n\n### \u9002\u914d\u5668\u5c42 (Adapter Layer)\n- **\u8f93\u5165\u9002\u914d\u5668**: HTTP API, gRPC, CLI\n- **\u8f93\u51fa\u9002\u914d\u5668**: \u6570\u636e\u5e93, \u6d88\u606f\u961f\u5217, \u7f13\u5b58\n\n### \u57fa\u7840\u8bbe\u65bd\u5c42 (Infrastructure Layer)\n- **\u4e8b\u4ef6\u5b58\u50a8**: PostgreSQL + NATS\n- **\u6295\u5f71\u5b58\u50a8**: PostgreSQL + Redis\n- **\u7f13\u5b58\u5c42**: Redis\u591a\u7ea7\u7f13\u5b58\n\n## \ud83c\udfaf \u4e8b\u4ef6\u6eaf\u6e90\u5b9e\u73b0\n\n### \u4e8b\u4ef6\u5b58\u50a8\n```go\n// \u4e8b\u4ef6\u5b58\u50a8\u63a5\u53e3\ntype EventStore interface {\n    Save(ctx context.Context, aggregateID string, events []interface{}, version int) error\n    Load(ctx context.Context, aggregateID string) ([]interface{}, error)\n    Publish(ctx context.Context, event interface{}) error\n    \n    // \u5feb\u7167\u652f\u6301\n    SaveSnapshot(ctx context.Context, aggregateID string, snapshot interface{}, version int) error\n    LoadSnapshot(ctx context.Context, aggregateID string) (interface{}, int, error)\n    GetSnapshotVersion(ctx context.Context, aggregateID string) (int, error)\n}\n\n// \u5feb\u7167\u63a5\u53e3\ntype Snapshot interface {\n    GetAggregateID() string\n    GetVersion() int\n    GetSnapshotData() interface{}\n}\n\n// \u805a\u5408\u6839\u5feb\u7167\u57fa\u7c7b\ntype AggregateSnapshot struct {\n    AggregateID string\n    Version     int\n    Data        interface{}\n}\n\nfunc (s *AggregateSnapshot) GetAggregateID() string {\n    return s.AggregateID\n}\n\nfunc (s *AggregateSnapshot) GetVersion() int {\n    return s.Version\n}\n\nfunc (s *AggregateSnapshot) GetSnapshotData() interface{} {\n    return s.Data\n}\n```\n\n### \u6295\u5f71\u7cfb\u7edf\n```go\n// \u6295\u5f71\u6784\u5efa\u5668\ntype Projection interface {\n    Project(ctx context.Context, event interface{}) error\n    Get(ctx context.Context, id string) (interface{}, error)\n}\n```\n\n## \ud83d\udcca \u6027\u80fd\u57fa\u51c6\n\n| \u64cd\u4f5c\u7c7b\u578b | \u54cd\u5e94\u65f6\u95f4      | \u5e76\u53d1\u80fd\u529b   |\n| -------- | ------------- | ---------- |\n| \u521b\u5efa\u805a\u5408 | < 50ms        | 1000+ TPS  |\n| \u67e5\u8be2\u6295\u5f71 | < 5ms         | 10000+ QPS |\n| \u4e8b\u4ef6\u91cd\u64ad | < 1s/1000\u4e8b\u4ef6 | \u53ef\u5e76\u884c     |\n| \u6295\u5f71\u66f4\u65b0 | < 100ms       | \u5b9e\u65f6\u66f4\u65b0   |\n\n## \ud83d\ude80 Bootstrap\u7cfb\u7edf\n\n### \u670d\u52a1\u5f15\u5bfc\u7a0b\u5e8f\n```go\n// \u4f7f\u7528Bootstrap\u542f\u52a8\u5e94\u7528\nfunc main() {\n    bootstrap.Run()\n}\n```\n\n### \u914d\u7f6e\u7ba1\u7406\n```go\n// \u4f7f\u7528Viper\u52a0\u8f7d\u914d\u7f6e\ncfg, err := config.LoadConfig()\n```\n\n### \u4f9d\u8d56\u6ce8\u5165\u5bb9\u5668\n```go\n// \u5bb9\u5668\u7ba1\u7406\u6240\u6709\u4f9d\u8d56\ncontainer := container.NewContainer(cfg)\ncontainer.InitInfrastructure(ctx)\ncontainer.InitRepositories()\ncontainer.InitUseCases()\ncontainer.InitHTTPServer()\n```\n\n### \u914d\u7f6e\u65b9\u5f0f\n\n#### 1. \u914d\u7f6e\u6587\u4ef6 (configs/app.yaml)\n```yaml\napp:\n  name: my-service\n  version: 1.0.0\n  environment: development\n  debug: true\n\ndatabase:\n  host: localhost\n  port: 5432\n  user: user\n  password: password\n  dbname: mydb\n```\n\n#### 2. \u73af\u5883\u53d8\u91cf\n```bash\n# \u6570\u636e\u5e93\u914d\u7f6e\nexport DB_HOST=localhost\nexport DB_PORT=5432\nexport DB_USER=user\nexport DB_PASSWORD=password\n\n# \u542f\u52a8\u5e94\u7528\n./scripts/start.sh\n```\n\n#### 3. .env\u6587\u4ef6\n```bash\n# \u590d\u5236\u73af\u5883\u53d8\u91cf\u6a21\u677f\ncp configs/.env.example configs/.env\n# \u7f16\u8f91\u914d\u7f6e\u6587\u4ef6\nvim configs/.env\n```\n\n## \ud83d\udee0\ufe0f \u5f00\u53d1\u5de5\u5177\n\n### \u4e00\u952e\u542f\u52a8\n```bash\n# \u5f00\u53d1\u73af\u5883\n./scripts/start.sh\n\n# \u751f\u4ea7\u73af\u5883\n./scripts/build.sh\ndocker-compose up -d\n```\n\n### \u6570\u636e\u5e93\u8fc1\u79fb\n```bash\n# \u81ea\u52a8\u8fc1\u79fb\ngo run cmd/migration/main.go\n\n# \u624b\u52a8\u8fc1\u79fb\npsql -h localhost -U user -d image_system -f migrations/001_create_events.up.sql\n```\n\n### \u6d4b\u8bd5\u547d\u4ee4\n```bash\n# \u5355\u5143\u6d4b\u8bd5\ngo test ./...\n\n# \u96c6\u6210\u6d4b\u8bd5\n./scripts/test.sh\n\n# \u6027\u80fd\u6d4b\u8bd5\n./scripts/benchmark.sh\n```\n\n## \ud83c\udfa8 DSL\u914d\u7f6e\u6307\u5357\n\n### \u914d\u7f6e\u6587\u4ef6\u7ed3\u6784\u8be6\u89e3\n\nPython\u751f\u6210\u5668\u4f7f\u7528YAML\u683c\u5f0f\u7684DSL\uff08\u9886\u57df\u7279\u5b9a\u8bed\u8a00\uff09\u6765\u5b9a\u4e49\u6574\u4e2a\u5fae\u670d\u52a1\u7684\u67b6\u6784\u3002\u914d\u7f6e\u6587\u4ef6\u652f\u6301\u4ee5\u4e0b\u9876\u7ea7\u914d\u7f6e\u9879\uff1a\n\n#### \ud83d\udccb \u9879\u76ee\u914d\u7f6e (project)\n\u5b9a\u4e49\u9879\u76ee\u7684\u57fa\u672c\u4fe1\u606f\uff1a\n\n```yaml\nproject:\n  name: my-service                    # \u9879\u76ee\u540d\u79f0\uff08\u5fc5\u586b\uff09- \u7528\u4e8e\u5305\u540d\u3001\u6a21\u5757\u540d\n  description: \u6211\u7684\u5fae\u670d\u52a1              # \u9879\u76ee\u63cf\u8ff0\uff08\u53ef\u9009\uff09- \u7528\u4e8eREADME\u6587\u6863\n  version: 1.0.0                    # \u7248\u672c\u53f7\uff08\u53ef\u9009\uff09- \u9ed8\u8ba4\u4e3a1.0.0\n  author: Your Name                 # \u4f5c\u8005\u4fe1\u606f\uff08\u53ef\u9009\uff09\n  go_version: 1.21                  # Go\u7248\u672c\uff08\u53ef\u9009\uff09- \u9ed8\u8ba4\u4e3a1.21\n```\n\n#### \ud83c\udfd7\ufe0f \u805a\u5408\u6839\u914d\u7f6e (aggregates)\n\u5b9a\u4e49\u4e1a\u52a1\u805a\u5408\u6839\uff0c\u6bcf\u4e2a\u805a\u5408\u6839\u5bf9\u5e94\u4e00\u4e2a\u6838\u5fc3\u4e1a\u52a1\u5b9e\u4f53\uff1a\n\n```yaml\naggregates:\n  - name: User                      # \u805a\u5408\u6839\u540d\u79f0\uff08\u5fc5\u586b\uff09- \u9996\u5b57\u6bcd\u5927\u5199\n    description: \u7528\u6237\u805a\u5408\u6839           # \u63cf\u8ff0\uff08\u53ef\u9009\uff09\n    fields:                         # \u805a\u5408\u6839\u5b57\u6bb5\u5b9a\u4e49\n      - name: username              # \u5b57\u6bb5\u540d\uff08\u5fc5\u586b\uff09\n        type: string                # Go\u7c7b\u578b\uff08\u5fc5\u586b\uff09- string/int/float64/bool/time.Time\n        json: username              # JSON\u6807\u7b7e\uff08\u53ef\u9009\uff09- \u9ed8\u8ba4\u4e3a\u5b57\u6bb5\u540d\u5c0f\u5199\n        gorm: uniqueIndex           # GORM\u6807\u7b7e\uff08\u53ef\u9009\uff09- \u652f\u6301\u6240\u6709GORM\u6807\u7b7e\n        validate: required,min=3    # \u9a8c\u8bc1\u6807\u7b7e\uff08\u53ef\u9009\uff09- \u652f\u6301go-playground/validator\n        description: \u7528\u6237\u540d           # \u5b57\u6bb5\u63cf\u8ff0\uff08\u53ef\u9009\uff09\n      \n      - name: email\n        type: string\n        json: email\n        validate: required,email\n        gorm: uniqueIndex\n        \n      - name: age\n        type: int\n        json: age\n        validate: min=0,max=150\n        \n      - name: active\n        type: bool\n        json: active\n        default: true                 # \u9ed8\u8ba4\u503c\uff08\u53ef\u9009\uff09\n```\n\n#### \u26a1 \u4e8b\u4ef6\u5b9a\u4e49 (events)\n\u6bcf\u4e2a\u805a\u5408\u6839\u53ef\u4ee5\u5b9a\u4e49\u591a\u4e2a\u9886\u57df\u4e8b\u4ef6\uff1a\n\n```yaml\n    events:\n      - name: UserCreated            # \u4e8b\u4ef6\u540d\u79f0\uff08\u5fc5\u586b\uff09- \u5fc5\u987b\u4ee5\u805a\u5408\u6839\u540d\u5f00\u5934\n        description: \u7528\u6237\u521b\u5efa\u4e8b\u4ef6      # \u4e8b\u4ef6\u63cf\u8ff0\uff08\u53ef\u9009\uff09\n        fields:                      # \u4e8b\u4ef6\u5b57\u6bb5\uff08\u53ef\u9009\uff09\n          - name: UserID\n            type: string\n            json: user_id\n            description: \u7528\u6237ID\n            \n          - name: Username\n            type: string\n            json: username\n            \n      - name: UserUpdated\n        description: \u7528\u6237\u66f4\u65b0\u4e8b\u4ef6\n        fields:\n          - name: UserID\n            type: string\n            json: user_id\n            \n          - name: UpdatedFields\n            type: map[string]interface{}  # \u652f\u6301\u590d\u6742\u7c7b\u578b\n            json: updated_fields\n            \n      - name: UserDeleted\n        description: \u7528\u6237\u5220\u9664\u4e8b\u4ef6\n        fields:\n          - name: UserID\n            type: string\n            json: user_id\n            \n          - name: DeletedAt\n            type: time.Time\n            json: deleted_at\n```\n\n#### \ud83d\udcca \u6295\u5f71\u914d\u7f6e (projections)\n\u5b9a\u4e49\u4e8b\u4ef6\u6295\u5f71\u6a21\u578b\uff08\u53ef\u9009\u914d\u7f6e\uff09\uff1a\n\n```yaml\nprojections:\n  - name: UserProjection            # \u6295\u5f71\u540d\u79f0\uff08\u5fc5\u586b\uff09\n    aggregate: User                 # \u5173\u8054\u7684\u805a\u5408\u6839\uff08\u5fc5\u586b\uff09\n    description: \u7528\u6237\u67e5\u8be2\u6295\u5f71        # \u63cf\u8ff0\uff08\u53ef\u9009\uff09\n    fields:                         # \u6295\u5f71\u5b57\u6bb5\u5b9a\u4e49\n      - name: ID\n        type: string\n        gorm: primaryKey\n        \n      - name: Username\n        type: string\n        gorm: index\n        \n      - name: Email\n        type: string\n        gorm: uniqueIndex\n        \n      - name: Active\n        type: bool\n        gorm: index\n```\n\n#### \ud83d\udd27 \u57fa\u7840\u8bbe\u65bd\u914d\u7f6e (infrastructure)\n\u5b9a\u4e49\u57fa\u7840\u8bbe\u65bd\u4f9d\u8d56\uff1a\n\n```yaml\ninfrastructure:\n  database:                       # \u6570\u636e\u5e93\u914d\u7f6e\n    type: postgresql              # \u652f\u6301postgresql/mysql/sqlite\n    host: localhost\n    port: 5432\n    database: myservice\n    username: user\n    password: password\n    \n  cache:                         # \u7f13\u5b58\u914d\u7f6e\n    type: redis                  # \u652f\u6301redis/memcached\n    host: localhost\n    port: 6379\n    \n  message_queue:               # \u6d88\u606f\u961f\u5217\n    type: nats                 # \u652f\u6301nats/rabbitmq/kafka\n    host: localhost\n    port: 4222\n    \n  monitoring:                  # \u76d1\u63a7\u914d\u7f6e\n    metrics: true              # \u542f\u7528Prometheus\u6307\u6807\n    tracing: true              # \u542f\u7528\u5206\u5e03\u5f0f\u8ffd\u8e2a\n    logging: zap               # \u65e5\u5fd7\u5e93\u9009\u62e9\n```\n\n#### \ud83c\udf10 API\u914d\u7f6e (api)\n\u5b9a\u4e49API\u63a5\u53e3\uff1a\n\n```yaml\napi:\n  http:                        # HTTP\u914d\u7f6e\n    enabled: true\n    port: 8080\n    prefix: /api/v1\n    \n  grpc:                       # gRPC\u914d\u7f6e\n    enabled: true\n    port: 50051\n    reflection: true          # \u542f\u7528\u670d\u52a1\u53cd\u5c04\n    \n  cors:                      # CORS\u914d\u7f6e\n    enabled: true\n    origins: [\"*\"]\n    methods: [\"GET\", \"POST\", \"PUT\", \"DELETE\"]\n    headers: [\"Content-Type\", \"Authorization\"]\n```\n\n#### \ud83d\udd17 \u4f1a\u8bdd\u7ba1\u7406 (session)\n\u5206\u5e03\u5f0f\u4f1a\u8bdd\u7ba1\u7406\u914d\u7f6e\uff0c\u7528\u4e8e\u957f\u65f6\u4efb\u52a1\u548cSaga\u4e8b\u52a1\uff1a\n\n```yaml\nsession:\n  enabled: true              # \u542f\u7528\u4f1a\u8bdd\u7ba1\u7406\n  \n  saga:                      # Saga\u914d\u7f6e\n    enabled: true\n    timeout: 30m             # Saga\u8d85\u65f6\u65f6\u95f4\n    compensation: true       # \u542f\u7528\u8865\u507f\u673a\u5236\n    \n  context:                   # \u4f1a\u8bdd\u4e0a\u4e0b\u6587\n    storage: redis          # \u5b58\u50a8\u540e\u7aef: redis/postgresql\n    ttl: 24h                # \u4f1a\u8bddTTL\n    compression: true       # \u542f\u7528\u538b\u7f29\n    \n  orchestration:            # \u7f16\u6392\u914d\u7f6e\n    pattern: choreography   # \u7f16\u6392\u6a21\u5f0f: choreography/orchestration\n    coordinator: enabled    # \u542f\u7528\u534f\u8c03\u5668\uff08\u4ec5orchestration\u6a21\u5f0f\uff09\n    \n  checkpoint:              # \u68c0\u67e5\u70b9\u673a\u5236\n    enabled: true\n    interval: 30s           # \u81ea\u52a8\u68c0\u67e5\u70b9\u95f4\u9694\n    storage: postgresql     # \u68c0\u67e5\u70b9\u5b58\u50a8\n    \n  recovery:                # \u6545\u969c\u6062\u590d\n    enabled: true\n    strategy: retry         # \u6062\u590d\u7b56\u7565: retry/rollback/compensate\n    max_retries: 3        # \u6700\u5927\u91cd\u8bd5\u6b21\u6570\n    backoff: exponential  # \u9000\u907f\u7b56\u7565\n```\n\n#### \ud83d\udd04 \u957f\u65f6\u4efb\u52a1 (long_running)\n\u957f\u65f6\u4efb\u52a1\u548c\u6279\u5904\u7406\u914d\u7f6e\uff1a\n\n```yaml\nlong_running:\n  enabled: true\n  \n  tasks:\n    - name: ImageProcessingTask\n      type: batch             # \u4efb\u52a1\u7c7b\u578b: batch/streaming\n      timeout: 2h\n      parallelism: 5         # \u5e76\u884c\u5ea6\n      \n      stages:               # \u5904\u7406\u9636\u6bb5\n        - name: Download\n          timeout: 10m\n          retry_policy: 3\n          \n        - name: Process\n          timeout: 1h\n          checkpoint: true   # \u542f\u7528\u68c0\u67e5\u70b9\n          \n        - name: Upload\n          timeout: 30m\n          retry_policy: 5\n          \n      context:              # \u4f1a\u8bdd\u4e0a\u4e0b\u6587\n        required_fields:\n          - user_id\n          - image_urls\n          - processing_config\n        \n        distributed_lock: true    # \u5206\u5e03\u5f0f\u9501\n        state_machine: true      # \u72b6\u6001\u673a\n        \n      compensation:         # \u8865\u507f\u673a\u5236\n        enabled: true\n        rollback_steps:\n          - DeleteTempFiles\n          - RevertDatabase\n          - SendNotification\n```\n\n### \u5b8c\u6574\u914d\u7f6e\u793a\u4f8b\n\n```yaml\n# \u5b8c\u6574\u9879\u76ee\u914d\u7f6e\u793a\u4f8b\nproject:\n  name: ecommerce-order-service\n  description: \u7535\u5546\u8ba2\u5355\u670d\u52a1 - \u652f\u6301\u8ba2\u5355\u521b\u5efa\u3001\u652f\u4ed8\u3001\u53d1\u8d27\u7b49\u5b8c\u6574\u751f\u547d\u5468\u671f\n  version: 2.1.0\n  author: \u67b6\u6784\u56e2\u961f\n  go_version: 1.21\n\naggregates:\n  - name: Order\n    description: \u8ba2\u5355\u805a\u5408\u6839\n    fields:\n      - name: OrderNumber\n        type: string\n        json: order_number\n        validate: required\n        gorm: uniqueIndex\n        description: \u8ba2\u5355\u53f7\n        \n      - name: CustomerID\n        type: string\n        json: customer_id\n        validate: required,uuid\n        gorm: index\n        description: \u5ba2\u6237ID\n        \n      - name: TotalAmount\n        type: float64\n        json: total_amount\n        validate: required,min=0\n        description: \u8ba2\u5355\u603b\u91d1\u989d\n        \n      - name: Status\n        type: string\n        json: status\n        validate: required,oneof=pending paid shipped delivered cancelled\n        gorm: index\n        default: pending\n        description: \u8ba2\u5355\u72b6\u6001\n        \n      - name: ShippingAddress\n        type: string\n        json: shipping_address\n        validate: required\n        description: \u6536\u8d27\u5730\u5740\n        \n    events:\n      - name: OrderCreated\n        description: \u8ba2\u5355\u521b\u5efa\u4e8b\u4ef6\n        fields:\n          - name: OrderID\n            type: string\n            json: order_id\n            validate: required,uuid\n            \n          - name: Items\n            type: \"[]OrderItem\"  # \u652f\u6301\u81ea\u5b9a\u4e49\u7c7b\u578b\n            json: items\n            \n      - name: OrderPaid\n        description: \u8ba2\u5355\u652f\u4ed8\u4e8b\u4ef6\n        fields:\n          - name: OrderID\n            type: string\n            json: order_id\n            \n          - name: PaymentID\n            type: string\n            json: payment_id\n            \n          - name: PaidAt\n            type: time.Time\n            json: paid_at\n            \n      - name: OrderShipped\n        description: \u8ba2\u5355\u53d1\u8d27\u4e8b\u4ef6\n        fields:\n          - name: OrderID\n            type: string\n            json: order_id\n            \n          - name: TrackingNumber\n            type: string\n            json: tracking_number\n            \n      - name: OrderDelivered\n        description: \u8ba2\u5355\u9001\u8fbe\u4e8b\u4ef6\n        fields:\n          - name: OrderID\n            type: string\n            json: order_id\n            \n          - name: DeliveredAt\n            type: time.Time\n            json: delivered_at\n\nprojections:\n  - name: OrderSummaryProjection\n    aggregate: Order\n    description: \u8ba2\u5355\u6458\u8981\u6295\u5f71 - \u7528\u4e8e\u67e5\u8be2\u8ba2\u5355\u5217\u8868\n    fields:\n      - name: ID\n        type: string\n        gorm: primaryKey\n        \n      - name: OrderNumber\n        type: string\n        gorm: uniqueIndex\n        \n      - name: CustomerID\n        type: string\n        gorm: index\n        \n      - name: TotalAmount\n        type: float64\n        \n      - name: Status\n        type: string\n        gorm: index\n        \n      - name: CreatedAt\n        type: time.Time\n        gorm: index\n\ninfrastructure:\n  database:\n    type: postgresql\n    host: localhost\n    port: 5432\n    database: ecommerce\n    username: ecommerce_user\n    password: secure_password\n    \n  cache:\n    type: redis\n    host: localhost\n    port: 6379\n    \n  message_queue:\n    type: nats\n    host: localhost\n    port: 4222\n    \n  monitoring:\n    metrics: true\n    tracing: true\n    logging: zap\n\napi:\n  http:\n    enabled: true\n    port: 8080\n    prefix: /api/v2\n    \n  grpc:\n    enabled: true\n    port: 50051\n    reflection: true\n    \n  cors:\n    enabled: true\n    origins: [\"https://frontend.com\", \"https://admin.com\"]\n    methods: [\"GET\", \"POST\", \"PUT\", \"DELETE\", \"OPTIONS\"]\n    headers: [\"Content-Type\", \"Authorization\", \"X-Requested-With\"]\n\nsession:\n  enabled: true\n  \n  saga:\n    enabled: true\n    timeout: 30m\n    compensation: true\n    \n  context:\n    storage: redis\n    ttl: 24h\n    compression: true\n    \n  orchestration:\n    pattern: choreography\n    coordinator: enabled\n    \n  checkpoint:\n    enabled: true\n    interval: 30s\n    storage: postgresql\n    \n  recovery:\n    enabled: true\n    strategy: retry\n    max_retries: 3\n    backoff: exponential\n\nlong_running:\n  enabled: true\n  \n  tasks:\n    - name: OrderFulfillmentTask\n      type: batch\n      timeout: 4h\n      parallelism: 3\n      \n      stages:\n        - name: InventoryCheck\n          timeout: 5m\n          retry_policy: 3\n          \n        - name: PaymentProcessing\n          timeout: 15m\n          checkpoint: true\n          \n        - name: ShippingArrangement\n          timeout: 1h\n          retry_policy: 2\n          \n        - name: Notification\n          timeout: 5m\n          \n      context:\n        required_fields:\n          - order_id\n          - customer_id\n          - payment_method\n          - shipping_address\n        \n        distributed_lock: true\n        state_machine: true\n        \n      compensation:\n        enabled: true\n        rollback_steps:\n          - ReleaseInventory\n          - RefundPayment\n          - CancelShipping\n          - SendCancellationNotification\n```\n\n### \u751f\u6210\u9879\u76ee\n\n\u4f7f\u7528\u914d\u7f6e\u6587\u4ef6\u751f\u6210\u9879\u76ee\uff1a\n\n```bash\n# \u57fa\u7840\u7528\u6cd5\npython3 clean-arch-generator.py --config my-service.yaml\n\n# \u6307\u5b9a\u8f93\u51fa\u76ee\u5f55\npython3 clean-arch-generator.py --config my-service.yaml --output ./projects/\n\n# \u4f7f\u7528\u81ea\u5b9a\u4e49\u9879\u76ee\u540d\npython3 clean-arch-generator.py --config my-service.yaml --project custom-name\n```\n\n### \u652f\u6301\u7684Go\u7c7b\u578b\u6620\u5c04\n\n| DSL\u7c7b\u578b                | Go\u7c7b\u578b                 | \u6570\u636e\u5e93\u7c7b\u578b   | \u63cf\u8ff0       |\n| ---------------------- | ---------------------- | ------------ | ---------- |\n| string                 | string                 | VARCHAR(255) | \u5b57\u7b26\u4e32     |\n| int                    | int                    | INTEGER      | \u6574\u6570       |\n| int64                  | int64                  | BIGINT       | \u5927\u6574\u6570     |\n| float64                | float64                | DECIMAL      | \u6d6e\u70b9\u6570     |\n| bool                   | bool                   | BOOLEAN      | \u5e03\u5c14\u503c     |\n| time.Time              | time.Time              | TIMESTAMP    | \u65f6\u95f4\u6233     |\n| uuid.UUID              | uuid.UUID              | UUID         | UUID       |\n| json.RawMessage        | json.RawMessage        | JSONB        | JSON\u6570\u636e   |\n| []string               | []string               | TEXT[]       | \u5b57\u7b26\u4e32\u6570\u7ec4 |\n| map[string]interface{} | map[string]interface{} | JSONB        | JSON\u5bf9\u8c61   |\n\n## \ud83d\udd27 \u6280\u672f\u6808\n\n### \u6838\u5fc3\u4f9d\u8d56\n- **Go**: 1.21+\n- **PostgreSQL**: 15+ (\u4e8b\u4ef6\u5b58\u50a8)\n- **Redis**: 7+ (\u7f13\u5b58\u548c\u6295\u5f71)\n- **NATS**: 2+ (\u6d88\u606f\u961f\u5217)\n\n### \u5f00\u53d1\u5de5\u5177\n- **Docker**: \u5bb9\u5668\u5316\u90e8\u7f72\n- **Docker Compose**: \u672c\u5730\u5f00\u53d1\n- **Make**: \u6784\u5efa\u5de5\u5177\n- **Air**: \u70ed\u91cd\u8f7d\n\n## \ud83c\udfaf \u4f1a\u8bdd\u7ba1\u7406\u67b6\u6784\n\n### \u5206\u5e03\u5f0f\u4f1a\u8bdd\u8bbe\u8ba1\n\n```\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502                    Session Management Layer                 \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502   Saga Manager  \u2502 Context Manager \u2502  Checkpoint Manager       \u2502\n\u2502                 \u2502                 \u2502                           \u2502\n\u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u2502\n\u2502 \u2502 Coordinator \u2502 \u2502 \u2502  Session    \u2502 \u2502 \u2502   State Machine     \u2502 \u2502\n\u2502 \u2502   / Choreo  \u2502 \u2502 \u2502  Context    \u2502 \u2502 \u2502   Recovery Engine   \u2502 \u2502\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                              \u2502\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502                    Storage Layer                           \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502     Redis       \u2502   PostgreSQL    \u2502     Event Store          \u2502\n\u2502  (Session TTL)  \u2502 (Checkpoint)    \u2502   (Event Log)            \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\n### \u4f1a\u8bdd\u4e0a\u4e0b\u6587\u7ed3\u6784\n\n```go\ntype SessionContext struct {\n    SessionID    string                 `json:\"session_id\"`\n    SagaID       string                 `json:\"saga_id\"`\n    WorkflowID   string                 `json:\"workflow_id\"`\n    \n    // \u6267\u884c\u72b6\u6001\n    CurrentStage string                 `json:\"current_stage\"`\n    StageIndex   int                    `json:\"stage_index\"`\n    Status       SessionStatus          `json:\"status\"`\n    \n    // \u4e1a\u52a1\u4e0a\u4e0b\u6587\n    Payload      map[string]interface{} `json:\"payload\"`\n    Metadata     map[string]string      `json:\"metadata\"`\n    \n    // \u65f6\u95f4\u63a7\u5236\n    CreatedAt    time.Time              `json:\"created_at\"`\n    UpdatedAt    time.Time              `json:\"updated_at\"`\n    ExpiresAt    time.Time              `json:\"expires_at\"`\n    \n    // \u6545\u969c\u6062\u590d\n    RetryCount   int                    `json:\"retry_count\"`\n    LastError    string                 `json:\"last_error\"`\n    \n    // \u5206\u5e03\u5f0f\u9501\n    LockToken    string                 `json:\"lock_token\"`\n    LockedBy     string                 `json:\"locked_by\"`\n    LockExpiry   time.Time              `json:\"lock_expiry\"`\n}\n```\n\n### \u4f1a\u8bdd\u751f\u547d\u5468\u671f\u7ba1\u7406\n\n```go\ntype SessionManager interface {\n    // \u4f1a\u8bdd\u521b\u5efa\n    CreateSession(ctx context.Context, workflowID string, payload map[string]interface{}) (*SessionContext, error)\n    \n    // \u72b6\u6001\u66f4\u65b0\n    UpdateStage(ctx context.Context, sessionID string, stage string, data map[string]interface{}) error\n    \n    // \u68c0\u67e5\u70b9\n    SaveCheckpoint(ctx context.Context, sessionID string, stageIndex int) error\n    \n    // \u6545\u969c\u6062\u590d\n    RecoverSession(ctx context.Context, sessionID string) (*SessionContext, error)\n    \n    // \u5206\u5e03\u5f0f\u9501\n    AcquireLock(ctx context.Context, sessionID string, instanceID string) (bool, error)\n    ReleaseLock(ctx context.Context, sessionID string, lockToken string) error\n    \n    // \u8865\u507f\u673a\u5236\n    Compensate(ctx context.Context, sessionID string, steps []string) error\n}\n```\n\n### \u5b9e\u9645\u4f7f\u7528\u793a\u4f8b\n\n#### 1. \u542f\u52a8\u957f\u65f6\u4efb\u52a1\u4f1a\u8bdd\n```go\n// \u521b\u5efa\u8ba2\u5355\u5c65\u7ea6\u4f1a\u8bdd\nsession, err := sessionManager.CreateSession(ctx, \"order-fulfillment\", map[string]interface{}{\n    \"order_id\":      order.ID,\n    \"customer_id\":   order.CustomerID,\n    \"payment_method\": order.PaymentMethod,\n    \"shipping_address\": order.ShippingAddress,\n})\n```\n\n#### 2. \u9636\u6bb5\u6267\u884c\u4e0e\u68c0\u67e5\u70b9\n```go\n// \u6267\u884c\u5e93\u5b58\u68c0\u67e5\u9636\u6bb5\nfunc (s *OrderFulfillmentService) executeInventoryCheck(ctx context.Context, sessionID string) error {\n    // \u83b7\u53d6\u4f1a\u8bdd\u4e0a\u4e0b\u6587\n    session, err := s.sessionManager.GetSession(ctx, sessionID)\n    if err != nil {\n        return fmt.Errorf(\"failed to get session: %w\", err)\n    }\n    \n    // \u6267\u884c\u4e1a\u52a1\u903b\u8f91\n    if err := s.inventoryService.CheckAvailability(ctx, session.Payload[\"order_id\"]); err != nil {\n        // \u4fdd\u5b58\u5931\u8d25\u72b6\u6001\n        s.sessionManager.UpdateStage(ctx, sessionID, \"inventory_check_failed\", map[string]interface{}{\n            \"error\": err.Error(),\n        })\n        return err\n    }\n    \n    // \u4fdd\u5b58\u68c0\u67e5\u70b9\n    return s.sessionManager.SaveCheckpoint(ctx, sessionID, 1)\n}\n```\n\n#### 3. \u6545\u969c\u6062\u590d\n```go\n// \u670d\u52a1\u91cd\u542f\u540e\u6062\u590d\u4f1a\u8bdd\nfunc (s *OrderFulfillmentService) recoverSessions(ctx context.Context) error {\n    // \u83b7\u53d6\u6240\u6709\u672a\u5b8c\u6210\u7684\u4f1a\u8bdd\n    sessions, err := s.sessionManager.GetActiveSessions(ctx)\n    if err != nil {\n        return err\n    }\n    \n    for _, session := range sessions {\n        // \u68c0\u67e5\u5206\u5e03\u5f0f\u9501\n        locked, err := s.sessionManager.AcquireLock(ctx, session.SessionID, s.instanceID)\n        if err != nil || !locked {\n            continue // \u5176\u4ed6\u5b9e\u4f8b\u6b63\u5728\u5904\u7406\n        }\n        \n        // \u6062\u590d\u6267\u884c\n        go s.resumeWorkflow(ctx, session)\n    }\n    \n    return nil\n}\n```\n\n### \u4f1a\u8bdd\u5b58\u50a8\u7b56\u7565\n\n#### Redis\u5b58\u50a8\uff08\u9ad8\u6027\u80fd\uff09\n```yaml\nsession:\n  context:\n    storage: redis\n    ttl: 24h\n    compression: true\n    key_prefix: \"session:\"\n    cluster_mode: true\n```\n\n#### PostgreSQL\u5b58\u50a8\uff08\u6301\u4e45\u5316\uff09\n```yaml\nsession:\n  context:\n    storage: postgresql\n    ttl: 7d\n    table_name: \"session_contexts\"\n    cleanup_interval: 1h\n```\n\n### \u6545\u969c\u6062\u590d\u7b56\u7565\n\n#### 1. \u91cd\u8bd5\u7b56\u7565\uff08Retry\uff09\n```go\n// \u6307\u6570\u9000\u907f\u91cd\u8bd5\nbackoff := &ExponentialBackoff{\n    InitialInterval: time.Second,\n    MaxInterval:     time.Minute,\n    Multiplier:      2.0,\n    MaxRetries:      3,\n}\n\nfor i := 0; i < backoff.MaxRetries; i++ {\n    err := executeStage(ctx, sessionID)\n    if err == nil {\n        break\n    }\n    \n    if i < backoff.MaxRetries-1 {\n        time.Sleep(backoff.NextInterval(i))\n    }\n}\n```\n\n#### 2. \u8865\u507f\u7b56\u7565\uff08Compensate\uff09\n```go\n// Saga\u8865\u507f\u673a\u5236\nfunc (s *OrderFulfillmentService) compensate(ctx context.Context, sessionID string) error {\n    session, _ := s.sessionManager.GetSession(ctx, sessionID)\n    \n    // \u9006\u5e8f\u6267\u884c\u8865\u507f\u6b65\u9aa4\n    for i := len(session.CompletedStages) - 1; i >= 0; i-- {\n        stage := session.CompletedStages[i]\n        \n        switch stage.Name {\n        case \"inventory_reserved\":\n            s.inventoryService.ReleaseReservation(ctx, session.Payload[\"order_id\"])\n        case \"payment_processed\":\n            s.paymentService.Refund(ctx, session.Payload[\"payment_id\"])\n        case \"shipping_arranged\":\n            s.shippingService.CancelShipment(ctx, session.Payload[\"shipment_id\"])\n        }\n    }\n    \n    return s.sessionManager.Compensate(ctx, sessionID, []string{\"all\"})\n}\n```\n\n## \ud83d\udcc8 \u6269\u5c55\u80fd\u529b\n\n## \ud83c\udf93 \u5b66\u4e60\u8d44\u6e90\n\n### \u6587\u6863\n- [\u6574\u6d01\u67b6\u6784\u6307\u5357](docs/architecture.md)\n- [API\u6587\u6863](docs/api.md)\n- [\u90e8\u7f72\u6307\u5357](docs/deployment.md)\n\n### \u793a\u4f8b\u9879\u76ee\n- [\u56fe\u7247\u7ba1\u7406\u7cfb\u7edf](examples/clean-arch-go-config.yaml)\n- [\u8ba2\u5355\u7cfb\u7edf](examples/order-system.yaml)\n- [\u7528\u6237\u7ba1\u7406\u7cfb\u7edf](examples/user-system.yaml)\n\n## \ud83e\udd1d \u8d21\u732e\u6307\u5357\n\n1. Fork\u9879\u76ee\n2. \u521b\u5efa\u529f\u80fd\u5206\u652f\n3. \u63d0\u4ea4Pull Request\n4. \u901a\u8fc7\u4ee3\u7801\u5ba1\u67e5\n\n## \ud83d\udcc4 \u8bb8\u53ef\u8bc1\n\nMIT License - \u81ea\u7531\u4f7f\u7528\uff0c\u6b22\u8fce\u8d21\u732e\uff01\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "\u57fa\u4e8e\u6574\u6d01\u67b6\u6784\u7684\u4e8b\u4ef6\u9a71\u52a8\u5fae\u670d\u52a1\u4ee3\u7801\u751f\u6210\u5668",
    "version": "1.0.0",
    "project_urls": {
        "Bug Tracker": "https://github.com/DotNetAge/micro-gen/issues",
        "Documentation": "https://micro-gen.readthedocs.io/",
        "Homepage": "https://github.com/DotNetAge/micro-gen",
        "Repository": "https://github.com/DotNetAge/micro-gen"
    },
    "split_keywords": [
        "microservice",
        " clean-architecture",
        " code-generator",
        " event-driven",
        " ddd"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "9ca451421e5f3b3eb9d12c1d64c92f1d3cf8f84084f46a80112459c50852e6f7",
                "md5": "380f128441a80f233f99cfad9fc98b59",
                "sha256": "0ef14fcbcde8285dd6ee5c3427576991bd0ebe047c41a46774df00cbbacc6c4f"
            },
            "downloads": -1,
            "filename": "micro_clean_gen-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "380f128441a80f233f99cfad9fc98b59",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 40567,
            "upload_time": "2025-08-29T07:53:59",
            "upload_time_iso_8601": "2025-08-29T07:53:59.254973Z",
            "url": "https://files.pythonhosted.org/packages/9c/a4/51421e5f3b3eb9d12c1d64c92f1d3cf8f84084f46a80112459c50852e6f7/micro_clean_gen-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "ae2063dbc755c49e83d9e7c24f7aa0af5ca206c008bde3857e1e831146dc0e47",
                "md5": "5161fd85c0ddfcf37a9de0cc4097048b",
                "sha256": "43d6a25f75c6b413ed5244f820370364e02902f762a80372cc94b247e9bdadea"
            },
            "downloads": -1,
            "filename": "micro_clean_gen-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "5161fd85c0ddfcf37a9de0cc4097048b",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 51358,
            "upload_time": "2025-08-29T07:54:00",
            "upload_time_iso_8601": "2025-08-29T07:54:00.841656Z",
            "url": "https://files.pythonhosted.org/packages/ae/20/63dbc755c49e83d9e7c24f7aa0af5ca206c008bde3857e1e831146dc0e47/micro_clean_gen-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-29 07:54:00",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "DotNetAge",
    "github_project": "micro-gen",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [
        {
            "name": "pyyaml",
            "specs": [
                [
                    ">=",
                    "6.0"
                ]
            ]
        },
        {
            "name": "jinja2",
            "specs": [
                [
                    ">=",
                    "3.1.0"
                ]
            ]
        },
        {
            "name": "click",
            "specs": [
                [
                    ">=",
                    "8.0.0"
                ]
            ]
        },
        {
            "name": "colorama",
            "specs": [
                [
                    ">=",
                    "0.4.4"
                ]
            ]
        },
        {
            "name": "pathlib2",
            "specs": [
                [
                    ">=",
                    "2.3.7"
                ]
            ]
        },
        {
            "name": "jsonschema",
            "specs": [
                [
                    ">=",
                    "4.0.0"
                ]
            ]
        },
        {
            "name": "loguru",
            "specs": [
                [
                    ">=",
                    "0.7.0"
                ]
            ]
        }
    ],
    "lcname": "micro-clean-gen"
}
        
Ray
Elapsed time: 1.35034s