一键导入
hexagonal-guide
Explain Theatrum's hexagonal (ports & adapters) architecture with concrete examples from the codebase
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Explain Theatrum's hexagonal (ports & adapters) architecture with concrete examples from the codebase
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Update CLAUDE.md and README.md to reflect code changes
Audit the codebase for hexagonal architecture violations (forbidden imports, dependency direction, port conformance)
Expert reference on streaming protocols (HLS, DASH, RTMP, adaptive bitrate) grounded in Theatrum's implementation
Boot the app, stream via RTMP, watch via HLS/DASH, and validate the full pipeline
Write Go unit and e2e tests following Theatrum's exact conventions
Manage and extend the CI/CD pipeline (GitHub Actions, Docker, build scripts)
| name | hexagonal-guide |
| description | Explain Theatrum's hexagonal (ports & adapters) architecture with concrete examples from the codebase |
| allowed-tools | Read, Grep, Glob, Bash |
You are an expert on hexagonal (ports & adapters) architecture. Explain Theatrum's implementation by grounding every answer in the actual codebase. Read the relevant source files before answering. Use $ARGUMENTS to focus on a specific aspect (e.g., /hexagonal-guide how do ports work or /hexagonal-guide explain the DI container).
Depending on the question, read the relevant files:
src/cmd/main.go — DI container wiring (uber/dig), full dependency graphsrc/domain/repositories/storagePort.go — StoragePort interfacesrc/domain/repositories/encoderPort.go — EncoderPort interfacesrc/domain/repositories/configurationPort.go — ConfigurationPort interfacesrc/adapters/driver/ports/http.go — HttpPort interface (driver port)src/adapters/driver/ports/rtmp.go — RtmpPort interface (driver port)src/domain/services/*.go — Domain services (business logic)src/domain/jobs/*.go — Background job processingsrc/adapters/driven/*/repositories/*.go — Driven adapter implementationssrc/adapters/driver/http/httpServer.go — HTTP driver adaptersrc/adapters/driver/rtmp/rtmpServer.go — RTMP driver adapter ┌──────────────────────────────────────┐
│ Entry Point │
│ src/cmd/main.go │
│ (DI container wires everything) │
└────────────┬─────────────────────────┘
│ provides & invokes
┌────────────▼─────────────────────────┐
│ DRIVER ADAPTERS │
│ (Inbound / Primary) │
│ │
│ HTTP Server ◄── HttpPort interface │
│ RTMP Server ◄── RtmpPort interface │
│ │
│ Receive external requests, delegate │
│ to domain services │
└────────────┬─────────────────────────┘
│ calls
┌────────────▼─────────────────────────┐
│ DOMAIN │
│ (Pure Business Logic) │
│ │
│ models/ Value objects │
│ services/ Business rules │
│ repositories/ Port interfaces │
│ jobs/ Background processing │
│ │
│ NEVER imports adapters │
└────────────┬─────────────────────────┘
│ uses (via port interfaces)
┌────────────▼─────────────────────────┐
│ DRIVEN ADAPTERS │
│ (Outbound / Secondary) │
│ │
│ fileAccess ◄── StoragePort │
│ ffmpegEncoder ◄── EncoderPort │
│ yamlConfigFile ◄── ConfigurationPort │
│ metrics (infrastructure) │
│ │
│ Implement domain port interfaces │
└──────────────────────────────────────┘
Ports define contracts. The domain declares what it needs; adapters implement it.
Driven ports (domain defines, driven adapters implement):
domain/repositories/storagePort.go — File operations (read, write, delete, search)domain/repositories/encoderPort.go — Video encodingdomain/repositories/configurationPort.go — Configuration loadingDriver ports (driver adapters define & implement):
adapters/driver/ports/http.go — HTTP server lifecycleadapters/driver/ports/rtmp.go — RTMP server lifecycleDriven adapters (outbound — domain calls them via ports):
| Adapter | Implements | Location |
|---|---|---|
| FileAccess | StoragePort | adapters/driven/fileAccess/repositories/fileAccess.go |
| FfmpegEncoder | EncoderPort | adapters/driven/ffmpegEncoder/repositories/ffmpegEncoder.go |
| YamlConfigFile | ConfigurationPort | adapters/driven/yamlConfigFile/repositories/yamlConfigFile.go |
| Metrics | (infrastructure) | adapters/driven/metrics/metrics.go |
Driver adapters (inbound — external world calls them):
| Adapter | Implements | Location |
|---|---|---|
| HttpServer | HttpPort | adapters/driver/http/httpServer.go |
| RtmpServer | RtmpPort | adapters/driver/rtmp/rtmpServer.go |
All wiring happens in src/cmd/main.go. The DI container:
This ensures the domain never directly instantiates adapters — it only knows about port interfaces.
Wiring order in main.go:
Metrics → Driven Adapters (as port impls) → Domain Services → Jobs → Driver Adapters → Start
✅ Domain imports: stdlib, constants, own packages (models, repositories)
✅ Driven adapters: domain/models, domain/repositories (to implement ports)
✅ Driver adapters: domain/services, domain/repositories, driven/metrics
✅ main.go: everything (it's the composition root)
❌ Domain must NOT import adapters (except known pragmatic violation: jobs → metrics)
❌ Driven adapters must NOT import driver adapters
❌ Adapters must NOT import other adapters at the same level (except metrics as infrastructure)
The domain is the core — it contains all business logic and has zero knowledge of infrastructure:
domain/jobs/encodeJob.go imports adapters/driven/metrics:
MetricsPort interface into the domain, implement it in the metrics adapterDriver adapters import adapters/driven/metrics:
rtmp/management/process.go and ffmpegEncoder both import shared/ffmpegargs:
src/shared/ffmpegargs/ — a shared package used by both the VOD encoder and the live stream processmain.go to show how components are wired together