@mytechtoday/augment-extensions 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/augment-extensions/coding-standards/c/CHANGELOG.md +55 -0
- package/augment-extensions/coding-standards/c/LICENSE +22 -0
- package/augment-extensions/coding-standards/c/README.md +167 -0
- package/augment-extensions/coding-standards/c/config/defaults.json +26 -0
- package/augment-extensions/coding-standards/c/config/examples/embedded.yaml +25 -0
- package/augment-extensions/coding-standards/c/config/examples/systems.json +31 -0
- package/augment-extensions/coding-standards/c/config/schema.json +244 -0
- package/augment-extensions/coding-standards/c/docs/API.md +613 -0
- package/augment-extensions/coding-standards/c/docs/CONFIGURATION.md +259 -0
- package/augment-extensions/coding-standards/c/docs/USER_GUIDE.md +567 -0
- package/augment-extensions/coding-standards/c/examples/drivers/Makefile +33 -0
- package/augment-extensions/coding-standards/c/examples/drivers/README.md +192 -0
- package/augment-extensions/coding-standards/c/examples/drivers/dma-example.c +224 -0
- package/augment-extensions/coding-standards/c/examples/drivers/example.dts +64 -0
- package/augment-extensions/coding-standards/c/examples/drivers/platform-driver.c +174 -0
- package/augment-extensions/coding-standards/c/examples/embedded/README.md +167 -0
- package/augment-extensions/coding-standards/c/examples/embedded/gpio-control.c +172 -0
- package/augment-extensions/coding-standards/c/examples/embedded/timer-isr.c +198 -0
- package/augment-extensions/coding-standards/c/examples/embedded/uart-communication.c +212 -0
- package/augment-extensions/coding-standards/c/examples/kernel/Makefile +82 -0
- package/augment-extensions/coding-standards/c/examples/kernel/README.md +168 -0
- package/augment-extensions/coding-standards/c/examples/kernel/char-device.c +198 -0
- package/augment-extensions/coding-standards/c/examples/kernel/proc-file.c +131 -0
- package/augment-extensions/coding-standards/c/examples/kernel/simple-module.c +111 -0
- package/augment-extensions/coding-standards/c/examples/legacy/Makefile +62 -0
- package/augment-extensions/coding-standards/c/examples/legacy/README.md +255 -0
- package/augment-extensions/coding-standards/c/examples/legacy/c89-to-c11-migration.c +268 -0
- package/augment-extensions/coding-standards/c/examples/legacy/compatibility-layer.c +239 -0
- package/augment-extensions/coding-standards/c/examples/networking/Makefile +35 -0
- package/augment-extensions/coding-standards/c/examples/networking/README.md +207 -0
- package/augment-extensions/coding-standards/c/examples/networking/protocol-parser.c +270 -0
- package/augment-extensions/coding-standards/c/examples/networking/tcp-server.c +197 -0
- package/augment-extensions/coding-standards/c/examples/networking/udp-multicast.c +220 -0
- package/augment-extensions/coding-standards/c/examples/realtime/Makefile +53 -0
- package/augment-extensions/coding-standards/c/examples/realtime/README.md +199 -0
- package/augment-extensions/coding-standards/c/examples/realtime/deadline-monitoring.c +260 -0
- package/augment-extensions/coding-standards/c/examples/realtime/priority-scheduling.c +258 -0
- package/augment-extensions/coding-standards/c/examples/systems/Makefile +34 -0
- package/augment-extensions/coding-standards/c/examples/systems/README.md +123 -0
- package/augment-extensions/coding-standards/c/examples/systems/ipc-pipes.c +181 -0
- package/augment-extensions/coding-standards/c/examples/systems/process-management.c +153 -0
- package/augment-extensions/coding-standards/c/examples/systems/signal-handling.c +162 -0
- package/augment-extensions/coding-standards/c/module.json +149 -0
- package/augment-extensions/coding-standards/c/rules/categories/drivers.md +635 -0
- package/augment-extensions/coding-standards/c/rules/categories/embedded.md +510 -0
- package/augment-extensions/coding-standards/c/rules/categories/kernel.md +653 -0
- package/augment-extensions/coding-standards/c/rules/categories/legacy.md +526 -0
- package/augment-extensions/coding-standards/c/rules/categories/networking.md +735 -0
- package/augment-extensions/coding-standards/c/rules/categories/realtime.md +631 -0
- package/augment-extensions/coding-standards/c/rules/categories/systems.md +586 -0
- package/augment-extensions/coding-standards/c/rules/universal/const-correctness.md +275 -0
- package/augment-extensions/coding-standards/c/rules/universal/documentation.md +251 -0
- package/augment-extensions/coding-standards/c/rules/universal/error-handling.md +250 -0
- package/augment-extensions/coding-standards/c/rules/universal/header-guards.md +254 -0
- package/augment-extensions/coding-standards/c/rules/universal/memory-safety.md +233 -0
- package/augment-extensions/coding-standards/c/rules/universal/naming.md +146 -0
- package/augment-extensions/coding-standards/c/src/conflict-detector.ts +461 -0
- package/augment-extensions/coding-standards/c/src/prompt-generator.ts +307 -0
- package/augment-extensions/coding-standards/c/src/rule-evaluator.ts +307 -0
- package/augment-extensions/coding-standards/c/src/rule-override.ts +427 -0
- package/augment-extensions/coding-standards/c/src/template-engine.ts +217 -0
- package/augment-extensions/coding-standards/c/templates/prompts/drivers.txt +191 -0
- package/augment-extensions/coding-standards/c/templates/prompts/embedded.txt +164 -0
- package/augment-extensions/coding-standards/c/templates/prompts/kernel.txt +175 -0
- package/augment-extensions/coding-standards/c/templates/prompts/legacy.txt +280 -0
- package/augment-extensions/coding-standards/c/templates/prompts/networking.txt +259 -0
- package/augment-extensions/coding-standards/c/templates/prompts/realtime.txt +219 -0
- package/augment-extensions/coding-standards/c/templates/prompts/systems.txt +147 -0
- package/augment-extensions/coding-standards/c/tests/integration/category-specific.test.ts +356 -0
- package/augment-extensions/coding-standards/c/tests/integration/end-to-end-workflow.test.ts +377 -0
- package/augment-extensions/coding-standards/c/tests/performance/benchmarks.test.ts +407 -0
- package/augment-extensions/coding-standards/c/tests/unit/config-manager.test.ts +345 -0
- package/augment-extensions/coding-standards/c/tests/unit/conflict-detector.test.ts +294 -0
- package/augment-extensions/coding-standards/c/tests/unit/prompt-generator.test.ts +174 -0
- package/augment-extensions/coding-standards/c/tests/unit/registry.test.ts +313 -0
- package/augment-extensions/coding-standards/c/tests/unit/rule-evaluator.test.ts +318 -0
- package/augment-extensions/coding-standards/c/tests/unit/rule-override.test.ts +326 -0
- package/augment-extensions/coding-standards/c/tests/unit/template-engine.test.ts +314 -0
- package/augment-extensions/coding-standards/go/CHARACTER-COUNT-REPORT.md +135 -0
- package/augment-extensions/coding-standards/go/PHASE1-COMPLETION.md +146 -0
- package/augment-extensions/coding-standards/go/PHASE4-COMPLETION.md +184 -0
- package/augment-extensions/coding-standards/go/README.md +200 -0
- package/augment-extensions/coding-standards/go/VALIDATION-CHECKLIST.md +154 -0
- package/augment-extensions/coding-standards/go/config/examples/example-cli.json +15 -0
- package/augment-extensions/coding-standards/go/config/examples/example-microservices.json +21 -0
- package/augment-extensions/coding-standards/go/config/examples/example-multi-category.yaml +24 -0
- package/augment-extensions/coding-standards/go/config/examples/example-web.json +15 -0
- package/augment-extensions/coding-standards/go/config/schema.json +110 -0
- package/augment-extensions/coding-standards/go/docs/CATEGORIES.md +221 -0
- package/augment-extensions/coding-standards/go/docs/CONFIGURATION.md +198 -0
- package/augment-extensions/coding-standards/go/docs/TROUBLESHOOTING.md +285 -0
- package/augment-extensions/coding-standards/go/examples/cli/cobra-app.go +287 -0
- package/augment-extensions/coding-standards/go/examples/cloud-native-app.go +217 -0
- package/augment-extensions/coding-standards/go/examples/devops-tool.go +250 -0
- package/augment-extensions/coding-standards/go/examples/distributed-system.go +247 -0
- package/augment-extensions/coding-standards/go/examples/microservices/grpc-service.go +253 -0
- package/augment-extensions/coding-standards/go/examples/rest-api.go +270 -0
- package/augment-extensions/coding-standards/go/examples/web/http-server.go +224 -0
- package/augment-extensions/coding-standards/go/module.json +139 -0
- package/augment-extensions/coding-standards/go/rules/categories/api-development/api-versioning.md +149 -0
- package/augment-extensions/coding-standards/go/rules/categories/api-development/rate-limiting.md +209 -0
- package/augment-extensions/coding-standards/go/rules/categories/api-development/rest-api-design.md +183 -0
- package/augment-extensions/coding-standards/go/rules/categories/cloud-native/cloud-config.md +193 -0
- package/augment-extensions/coding-standards/go/rules/categories/cloud-native/health-checks.md +231 -0
- package/augment-extensions/coding-standards/go/rules/categories/cloud-native/kubernetes.md +180 -0
- package/augment-extensions/coding-standards/go/rules/categories/devops-tooling/automation.md +179 -0
- package/augment-extensions/coding-standards/go/rules/categories/devops-tooling/ci-cd-integration.md +147 -0
- package/augment-extensions/coding-standards/go/rules/categories/devops-tooling/infrastructure-as-code.md +231 -0
- package/augment-extensions/coding-standards/go/rules/categories/distributed-systems/caching.md +150 -0
- package/augment-extensions/coding-standards/go/rules/categories/distributed-systems/consensus.md +187 -0
- package/augment-extensions/coding-standards/go/rules/categories/distributed-systems/event-sourcing.md +246 -0
- package/augment-extensions/coding-standards/go/rules/cli/command-parsing.md +264 -0
- package/augment-extensions/coding-standards/go/rules/cli/configuration.md +268 -0
- package/augment-extensions/coding-standards/go/rules/cli/cross-platform.md +324 -0
- package/augment-extensions/coding-standards/go/rules/microservices/distributed-tracing.md +253 -0
- package/augment-extensions/coding-standards/go/rules/microservices/grpc.md +257 -0
- package/augment-extensions/coding-standards/go/rules/microservices/metrics.md +278 -0
- package/augment-extensions/coding-standards/go/rules/microservices/service-discovery.md +249 -0
- package/augment-extensions/coding-standards/go/rules/universal/code-organization.md +221 -0
- package/augment-extensions/coding-standards/go/rules/universal/documentation.md +269 -0
- package/augment-extensions/coding-standards/go/rules/universal/performance.md +323 -0
- package/augment-extensions/coding-standards/go/rules/universal/testing.md +162 -0
- package/augment-extensions/coding-standards/go/rules/web/graceful-shutdown.md +249 -0
- package/augment-extensions/coding-standards/go/rules/web/http-handlers.md +164 -0
- package/augment-extensions/coding-standards/go/rules/web/middleware.md +234 -0
- package/augment-extensions/coding-standards/go/rules/web/routing.md +251 -0
- package/augment-extensions/coding-standards/go/templates/prompts/api.md +160 -0
- package/augment-extensions/coding-standards/go/templates/prompts/cli.md +225 -0
- package/augment-extensions/coding-standards/go/templates/prompts/cloud-native.md +121 -0
- package/augment-extensions/coding-standards/go/templates/prompts/devops.md +146 -0
- package/augment-extensions/coding-standards/go/templates/prompts/distributed.md +133 -0
- package/augment-extensions/coding-standards/go/templates/prompts/microservices.md +225 -0
- package/augment-extensions/coding-standards/go/templates/prompts/web.md +181 -0
- package/augment-extensions/coding-standards/go/tests/integration/module-integration.test.ts +164 -0
- package/augment-extensions/coding-standards/go/tests/unit/category-selection.test.ts +147 -0
- package/augment-extensions/coding-standards/go/tests/unit/module-structure.test.ts +154 -0
- package/augment-extensions/coding-standards/go/tests/validate-character-count.ps1 +13 -0
- package/augment-extensions/coding-standards/go/tests/validate-examples.ps1 +148 -0
- package/augment-extensions/coding-standards/go/tests/validate-examples.sh +135 -0
- package/cli/dist/analysis/ast-parser.d.ts +47 -0
- package/cli/dist/analysis/ast-parser.d.ts.map +1 -0
- package/cli/dist/analysis/ast-parser.js +161 -0
- package/cli/dist/analysis/ast-parser.js.map +1 -0
- package/cli/dist/analysis/complexity-analyzer.d.ts +27 -0
- package/cli/dist/analysis/complexity-analyzer.d.ts.map +1 -0
- package/cli/dist/analysis/complexity-analyzer.js +189 -0
- package/cli/dist/analysis/complexity-analyzer.js.map +1 -0
- package/cli/dist/analysis/dependency-analyzer.d.ts +23 -0
- package/cli/dist/analysis/dependency-analyzer.d.ts.map +1 -0
- package/cli/dist/analysis/dependency-analyzer.js +237 -0
- package/cli/dist/analysis/dependency-analyzer.js.map +1 -0
- package/cli/dist/analysis/index.d.ts +9 -0
- package/cli/dist/analysis/index.d.ts.map +1 -0
- package/cli/dist/analysis/index.js +25 -0
- package/cli/dist/analysis/index.js.map +1 -0
- package/cli/dist/analysis/security-scanner.d.ts +11 -0
- package/cli/dist/analysis/security-scanner.d.ts.map +1 -0
- package/cli/dist/analysis/security-scanner.js +294 -0
- package/cli/dist/analysis/security-scanner.js.map +1 -0
- package/cli/dist/analysis/types.d.ts +151 -0
- package/cli/dist/analysis/types.d.ts.map +1 -0
- package/cli/dist/analysis/types.js +6 -0
- package/cli/dist/analysis/types.js.map +1 -0
- package/cli/dist/cli.js +24 -0
- package/cli/dist/cli.js.map +1 -1
- package/cli/dist/commands/code-analysis.d.ts +11 -0
- package/cli/dist/commands/code-analysis.d.ts.map +1 -0
- package/cli/dist/commands/code-analysis.js +412 -0
- package/cli/dist/commands/code-analysis.js.map +1 -0
- package/modules.md +99 -3
- package/package.json +14 -2
- package/cli/dist/commands/agent.d.ts +0 -37
- package/cli/dist/commands/agent.d.ts.map +0 -1
- package/cli/dist/commands/agent.js +0 -222
- package/cli/dist/commands/agent.js.map +0 -1
- package/cli/dist/commands/beads.d.ts +0 -64
- package/cli/dist/commands/beads.d.ts.map +0 -1
- package/cli/dist/commands/beads.js +0 -377
- package/cli/dist/commands/beads.js.map +0 -1
- package/cli/dist/commands/change.d.ts +0 -54
- package/cli/dist/commands/change.d.ts.map +0 -1
- package/cli/dist/commands/change.js +0 -243
- package/cli/dist/commands/change.js.map +0 -1
- package/cli/dist/commands/clean.d.ts +0 -15
- package/cli/dist/commands/clean.d.ts.map +0 -1
- package/cli/dist/commands/clean.js +0 -63
- package/cli/dist/commands/clean.js.map +0 -1
- package/cli/dist/commands/clone.d.ts +0 -15
- package/cli/dist/commands/clone.d.ts.map +0 -1
- package/cli/dist/commands/clone.js +0 -49
- package/cli/dist/commands/clone.js.map +0 -1
- package/cli/dist/commands/config.d.ts +0 -33
- package/cli/dist/commands/config.d.ts.map +0 -1
- package/cli/dist/commands/config.js +0 -166
- package/cli/dist/commands/config.js.map +0 -1
- package/cli/dist/commands/context.d.ts +0 -38
- package/cli/dist/commands/context.d.ts.map +0 -1
- package/cli/dist/commands/context.js +0 -205
- package/cli/dist/commands/context.js.map +0 -1
- package/cli/dist/commands/create.d.ts +0 -18
- package/cli/dist/commands/create.d.ts.map +0 -1
- package/cli/dist/commands/create.js +0 -178
- package/cli/dist/commands/create.js.map +0 -1
- package/cli/dist/commands/diff.d.ts +0 -19
- package/cli/dist/commands/diff.d.ts.map +0 -1
- package/cli/dist/commands/diff.js +0 -104
- package/cli/dist/commands/diff.js.map +0 -1
- package/cli/dist/commands/doctor.d.ts +0 -14
- package/cli/dist/commands/doctor.d.ts.map +0 -1
- package/cli/dist/commands/doctor.js +0 -62
- package/cli/dist/commands/doctor.js.map +0 -1
- package/cli/dist/commands/export.d.ts +0 -28
- package/cli/dist/commands/export.d.ts.map +0 -1
- package/cli/dist/commands/export.js +0 -135
- package/cli/dist/commands/export.js.map +0 -1
- package/cli/dist/commands/import.d.ts +0 -23
- package/cli/dist/commands/import.d.ts.map +0 -1
- package/cli/dist/commands/import.js +0 -118
- package/cli/dist/commands/import.js.map +0 -1
- package/cli/dist/commands/prompt.d.ts +0 -45
- package/cli/dist/commands/prompt.d.ts.map +0 -1
- package/cli/dist/commands/prompt.js +0 -223
- package/cli/dist/commands/prompt.js.map +0 -1
- package/cli/dist/commands/spec.d.ts +0 -57
- package/cli/dist/commands/spec.d.ts.map +0 -1
- package/cli/dist/commands/spec.js +0 -279
- package/cli/dist/commands/spec.js.map +0 -1
- package/cli/dist/commands/stats.d.ts +0 -18
- package/cli/dist/commands/stats.d.ts.map +0 -1
- package/cli/dist/commands/stats.js +0 -85
- package/cli/dist/commands/stats.js.map +0 -1
- package/cli/dist/commands/task.d.ts +0 -65
- package/cli/dist/commands/task.d.ts.map +0 -1
- package/cli/dist/commands/task.js +0 -282
- package/cli/dist/commands/task.js.map +0 -1
- package/cli/dist/commands/template.d.ts +0 -17
- package/cli/dist/commands/template.d.ts.map +0 -1
- package/cli/dist/commands/template.js +0 -55
- package/cli/dist/commands/template.js.map +0 -1
- package/cli/dist/utils/agent-config.d.ts +0 -129
- package/cli/dist/utils/agent-config.d.ts.map +0 -1
- package/cli/dist/utils/agent-config.js +0 -297
- package/cli/dist/utils/agent-config.js.map +0 -1
- package/cli/dist/utils/beads-graph.d.ts +0 -17
- package/cli/dist/utils/beads-graph.d.ts.map +0 -1
- package/cli/dist/utils/beads-graph.js +0 -150
- package/cli/dist/utils/beads-graph.js.map +0 -1
- package/cli/dist/utils/beads-integration.d.ts +0 -112
- package/cli/dist/utils/beads-integration.d.ts.map +0 -1
- package/cli/dist/utils/beads-integration.js +0 -312
- package/cli/dist/utils/beads-integration.js.map +0 -1
- package/cli/dist/utils/beads-reporter.d.ts +0 -17
- package/cli/dist/utils/beads-reporter.d.ts.map +0 -1
- package/cli/dist/utils/beads-reporter.js +0 -160
- package/cli/dist/utils/beads-reporter.js.map +0 -1
- package/cli/dist/utils/cache-manager.d.ts +0 -55
- package/cli/dist/utils/cache-manager.d.ts.map +0 -1
- package/cli/dist/utils/cache-manager.js +0 -150
- package/cli/dist/utils/cache-manager.js.map +0 -1
- package/cli/dist/utils/change-manager.d.ts +0 -70
- package/cli/dist/utils/change-manager.d.ts.map +0 -1
- package/cli/dist/utils/change-manager.js +0 -412
- package/cli/dist/utils/change-manager.js.map +0 -1
- package/cli/dist/utils/config-manager-enhanced.d.ts +0 -66
- package/cli/dist/utils/config-manager-enhanced.d.ts.map +0 -1
- package/cli/dist/utils/config-manager-enhanced.js +0 -77
- package/cli/dist/utils/config-manager-enhanced.js.map +0 -1
- package/cli/dist/utils/context-manager.d.ts +0 -96
- package/cli/dist/utils/context-manager.d.ts.map +0 -1
- package/cli/dist/utils/context-manager.js +0 -258
- package/cli/dist/utils/context-manager.js.map +0 -1
- package/cli/dist/utils/diff-engine.d.ts +0 -78
- package/cli/dist/utils/diff-engine.d.ts.map +0 -1
- package/cli/dist/utils/diff-engine.js +0 -233
- package/cli/dist/utils/diff-engine.js.map +0 -1
- package/cli/dist/utils/export-system.d.ts +0 -101
- package/cli/dist/utils/export-system.d.ts.map +0 -1
- package/cli/dist/utils/export-system.js +0 -289
- package/cli/dist/utils/export-system.js.map +0 -1
- package/cli/dist/utils/health-checker.d.ts +0 -66
- package/cli/dist/utils/health-checker.d.ts.map +0 -1
- package/cli/dist/utils/health-checker.js +0 -285
- package/cli/dist/utils/health-checker.js.map +0 -1
- package/cli/dist/utils/import-system.d.ts +0 -74
- package/cli/dist/utils/import-system.d.ts.map +0 -1
- package/cli/dist/utils/import-system.js +0 -317
- package/cli/dist/utils/import-system.js.map +0 -1
- package/cli/dist/utils/module-cloner.d.ts +0 -40
- package/cli/dist/utils/module-cloner.d.ts.map +0 -1
- package/cli/dist/utils/module-cloner.js +0 -136
- package/cli/dist/utils/module-cloner.js.map +0 -1
- package/cli/dist/utils/prompt-manager.d.ts +0 -90
- package/cli/dist/utils/prompt-manager.d.ts.map +0 -1
- package/cli/dist/utils/prompt-manager.js +0 -302
- package/cli/dist/utils/prompt-manager.js.map +0 -1
- package/cli/dist/utils/spec-manager.d.ts +0 -65
- package/cli/dist/utils/spec-manager.d.ts.map +0 -1
- package/cli/dist/utils/spec-manager.js +0 -329
- package/cli/dist/utils/spec-manager.js.map +0 -1
- package/cli/dist/utils/stats-collector.d.ts +0 -74
- package/cli/dist/utils/stats-collector.d.ts.map +0 -1
- package/cli/dist/utils/stats-collector.js +0 -164
- package/cli/dist/utils/stats-collector.js.map +0 -1
- package/cli/dist/utils/template-engine.d.ts +0 -47
- package/cli/dist/utils/template-engine.d.ts.map +0 -1
- package/cli/dist/utils/template-engine.js +0 -204
- package/cli/dist/utils/template-engine.js.map +0 -1
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# Event Sourcing Rules
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Best practices for implementing event sourcing patterns in Go applications including event stores, projections, and CQRS.
|
|
6
|
+
|
|
7
|
+
## Rules
|
|
8
|
+
|
|
9
|
+
### 1. Design Immutable Events
|
|
10
|
+
|
|
11
|
+
**Rule**: Events should be immutable and contain all necessary information.
|
|
12
|
+
|
|
13
|
+
**Good Example**:
|
|
14
|
+
```go
|
|
15
|
+
type Event struct {
|
|
16
|
+
ID string `json:"id"`
|
|
17
|
+
AggregateID string `json:"aggregate_id"`
|
|
18
|
+
Type string `json:"type"`
|
|
19
|
+
Data json.RawMessage `json:"data"`
|
|
20
|
+
Metadata map[string]string `json:"metadata"`
|
|
21
|
+
Timestamp time.Time `json:"timestamp"`
|
|
22
|
+
Version int `json:"version"`
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type UserCreatedEvent struct {
|
|
26
|
+
UserID string `json:"user_id"`
|
|
27
|
+
Email string `json:"email"`
|
|
28
|
+
Name string `json:"name"`
|
|
29
|
+
CreatedAt time.Time `json:"created_at"`
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
func NewUserCreatedEvent(userID, email, name string) (*Event, error) {
|
|
33
|
+
data, err := json.Marshal(UserCreatedEvent{
|
|
34
|
+
UserID: userID,
|
|
35
|
+
Email: email,
|
|
36
|
+
Name: name,
|
|
37
|
+
CreatedAt: time.Now(),
|
|
38
|
+
})
|
|
39
|
+
if err != nil {
|
|
40
|
+
return nil, err
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return &Event{
|
|
44
|
+
ID: uuid.New().String(),
|
|
45
|
+
AggregateID: userID,
|
|
46
|
+
Type: "UserCreated",
|
|
47
|
+
Data: data,
|
|
48
|
+
Timestamp: time.Now(),
|
|
49
|
+
Version: 1,
|
|
50
|
+
}, nil
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 2. Implement Event Store Interface
|
|
55
|
+
|
|
56
|
+
**Rule**: Define a clear event store interface for persistence.
|
|
57
|
+
|
|
58
|
+
**Good Example**:
|
|
59
|
+
```go
|
|
60
|
+
type EventStore interface {
|
|
61
|
+
Save(ctx context.Context, events []Event) error
|
|
62
|
+
Load(ctx context.Context, aggregateID string) ([]Event, error)
|
|
63
|
+
LoadFrom(ctx context.Context, aggregateID string, version int) ([]Event, error)
|
|
64
|
+
Subscribe(ctx context.Context, eventTypes []string) (<-chan Event, error)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
type PostgresEventStore struct {
|
|
68
|
+
db *sql.DB
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
func (s *PostgresEventStore) Save(ctx context.Context, events []Event) error {
|
|
72
|
+
tx, err := s.db.BeginTx(ctx, nil)
|
|
73
|
+
if err != nil {
|
|
74
|
+
return err
|
|
75
|
+
}
|
|
76
|
+
defer tx.Rollback()
|
|
77
|
+
|
|
78
|
+
for _, event := range events {
|
|
79
|
+
_, err := tx.ExecContext(ctx,
|
|
80
|
+
`INSERT INTO events (id, aggregate_id, type, data, metadata, timestamp, version)
|
|
81
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7)`,
|
|
82
|
+
event.ID, event.AggregateID, event.Type, event.Data,
|
|
83
|
+
event.Metadata, event.Timestamp, event.Version,
|
|
84
|
+
)
|
|
85
|
+
if err != nil {
|
|
86
|
+
return err
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return tx.Commit()
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### 3. Implement Aggregate Root Pattern
|
|
95
|
+
|
|
96
|
+
**Rule**: Use aggregate roots to ensure consistency boundaries.
|
|
97
|
+
|
|
98
|
+
**Good Example**:
|
|
99
|
+
```go
|
|
100
|
+
type User struct {
|
|
101
|
+
ID string
|
|
102
|
+
Email string
|
|
103
|
+
Name string
|
|
104
|
+
Version int
|
|
105
|
+
changes []Event
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
func (u *User) ApplyEvent(event Event) error {
|
|
109
|
+
switch event.Type {
|
|
110
|
+
case "UserCreated":
|
|
111
|
+
var data UserCreatedEvent
|
|
112
|
+
if err := json.Unmarshal(event.Data, &data); err != nil {
|
|
113
|
+
return err
|
|
114
|
+
}
|
|
115
|
+
u.ID = data.UserID
|
|
116
|
+
u.Email = data.Email
|
|
117
|
+
u.Name = data.Name
|
|
118
|
+
|
|
119
|
+
case "UserEmailChanged":
|
|
120
|
+
var data UserEmailChangedEvent
|
|
121
|
+
if err := json.Unmarshal(event.Data, &data); err != nil {
|
|
122
|
+
return err
|
|
123
|
+
}
|
|
124
|
+
u.Email = data.NewEmail
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
u.Version = event.Version
|
|
128
|
+
return nil
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
func (u *User) ChangeEmail(newEmail string) error {
|
|
132
|
+
if newEmail == u.Email {
|
|
133
|
+
return fmt.Errorf("email unchanged")
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
event, err := NewUserEmailChangedEvent(u.ID, u.Email, newEmail)
|
|
137
|
+
if err != nil {
|
|
138
|
+
return err
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
u.changes = append(u.changes, *event)
|
|
142
|
+
return u.ApplyEvent(*event)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
func (u *User) GetUncommittedChanges() []Event {
|
|
146
|
+
return u.changes
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
func (u *User) MarkChangesAsCommitted() {
|
|
150
|
+
u.changes = nil
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### 4. Build Projections for Read Models
|
|
155
|
+
|
|
156
|
+
**Rule**: Create separate read models (projections) from events.
|
|
157
|
+
|
|
158
|
+
**Good Example**:
|
|
159
|
+
```go
|
|
160
|
+
type UserProjection struct {
|
|
161
|
+
ID string
|
|
162
|
+
Email string
|
|
163
|
+
Name string
|
|
164
|
+
CreatedAt time.Time
|
|
165
|
+
UpdatedAt time.Time
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
type ProjectionBuilder struct {
|
|
169
|
+
db *sql.DB
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
func (pb *ProjectionBuilder) HandleEvent(ctx context.Context, event Event) error {
|
|
173
|
+
switch event.Type {
|
|
174
|
+
case "UserCreated":
|
|
175
|
+
return pb.handleUserCreated(ctx, event)
|
|
176
|
+
case "UserEmailChanged":
|
|
177
|
+
return pb.handleUserEmailChanged(ctx, event)
|
|
178
|
+
}
|
|
179
|
+
return nil
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
func (pb *ProjectionBuilder) handleUserCreated(ctx context.Context, event Event) error {
|
|
183
|
+
var data UserCreatedEvent
|
|
184
|
+
if err := json.Unmarshal(event.Data, &data); err != nil {
|
|
185
|
+
return err
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
_, err := pb.db.ExecContext(ctx,
|
|
189
|
+
`INSERT INTO user_projections (id, email, name, created_at, updated_at)
|
|
190
|
+
VALUES ($1, $2, $3, $4, $5)`,
|
|
191
|
+
data.UserID, data.Email, data.Name, data.CreatedAt, time.Now(),
|
|
192
|
+
)
|
|
193
|
+
return err
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### 5. Implement Event Versioning
|
|
198
|
+
|
|
199
|
+
**Rule**: Support event schema evolution with versioning.
|
|
200
|
+
|
|
201
|
+
**Good Example**:
|
|
202
|
+
```go
|
|
203
|
+
type EventUpgrader interface {
|
|
204
|
+
Upgrade(event Event) (Event, error)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
type UserCreatedV1ToV2 struct{}
|
|
208
|
+
|
|
209
|
+
func (u *UserCreatedV1ToV2) Upgrade(event Event) (Event, error) {
|
|
210
|
+
if event.Version != 1 {
|
|
211
|
+
return event, nil
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
var v1Data struct {
|
|
215
|
+
UserID string `json:"user_id"`
|
|
216
|
+
Email string `json:"email"`
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if err := json.Unmarshal(event.Data, &v1Data); err != nil {
|
|
220
|
+
return event, err
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
v2Data := UserCreatedEvent{
|
|
224
|
+
UserID: v1Data.UserID,
|
|
225
|
+
Email: v1Data.Email,
|
|
226
|
+
Name: "Unknown", // Default for missing field
|
|
227
|
+
CreatedAt: event.Timestamp,
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
data, err := json.Marshal(v2Data)
|
|
231
|
+
if err != nil {
|
|
232
|
+
return event, err
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
event.Data = data
|
|
236
|
+
event.Version = 2
|
|
237
|
+
|
|
238
|
+
return event, nil
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## References
|
|
243
|
+
|
|
244
|
+
- [Event Sourcing Pattern](https://martinfowler.com/eaaDev/EventSourcing.html)
|
|
245
|
+
- [CQRS Pattern](https://martinfowler.com/bliki/CQRS.html)
|
|
246
|
+
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# Go CLI Tools - Command Parsing
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Command parsing is fundamental to CLI tools. This document defines best practices for implementing command-line interfaces using Cobra in Go.
|
|
6
|
+
|
|
7
|
+
## Core Principles
|
|
8
|
+
|
|
9
|
+
1. **User Experience**: Provide clear help text and examples
|
|
10
|
+
2. **Subcommands**: Organize functionality into logical subcommands
|
|
11
|
+
3. **Flags**: Use flags for options and arguments for required inputs
|
|
12
|
+
4. **Validation**: Validate inputs early and provide helpful error messages
|
|
13
|
+
5. **Consistency**: Follow Unix conventions for CLI design
|
|
14
|
+
|
|
15
|
+
## Rules
|
|
16
|
+
|
|
17
|
+
### GOL.3.3.1.1: Use Cobra for Command Parsing
|
|
18
|
+
|
|
19
|
+
**Rule**: Use Cobra library for building CLI applications with subcommands.
|
|
20
|
+
|
|
21
|
+
**Severity**: WARNING
|
|
22
|
+
|
|
23
|
+
**Rationale**: Cobra provides robust command parsing, help generation, and follows CLI best practices.
|
|
24
|
+
|
|
25
|
+
**✅ Good**:
|
|
26
|
+
```go
|
|
27
|
+
import (
|
|
28
|
+
"github.com/spf13/cobra"
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
var rootCmd = &cobra.Command{
|
|
32
|
+
Use: "myapp",
|
|
33
|
+
Short: "A brief description of your application",
|
|
34
|
+
Long: `A longer description that spans multiple lines and likely contains
|
|
35
|
+
examples and usage of using your application.`,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
var versionCmd = &cobra.Command{
|
|
39
|
+
Use: "version",
|
|
40
|
+
Short: "Print the version number",
|
|
41
|
+
Run: func(cmd *cobra.Command, args []string) {
|
|
42
|
+
fmt.Println("myapp v1.0.0")
|
|
43
|
+
},
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
func init() {
|
|
47
|
+
rootCmd.AddCommand(versionCmd)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
func Execute() error {
|
|
51
|
+
return rootCmd.Execute()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
func main() {
|
|
55
|
+
if err := Execute(); err != nil {
|
|
56
|
+
os.Exit(1)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### GOL.3.3.1.2: Organize Commands with Subcommands
|
|
62
|
+
|
|
63
|
+
**Rule**: Use subcommands to organize related functionality.
|
|
64
|
+
|
|
65
|
+
**Severity**: INFO
|
|
66
|
+
|
|
67
|
+
**Rationale**: Subcommands provide clear organization and discoverability.
|
|
68
|
+
|
|
69
|
+
**✅ Good**:
|
|
70
|
+
```go
|
|
71
|
+
var userCmd = &cobra.Command{
|
|
72
|
+
Use: "user",
|
|
73
|
+
Short: "Manage users",
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
var userListCmd = &cobra.Command{
|
|
77
|
+
Use: "list",
|
|
78
|
+
Short: "List all users",
|
|
79
|
+
Run: func(cmd *cobra.Command, args []string) {
|
|
80
|
+
// List users
|
|
81
|
+
},
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
var userCreateCmd = &cobra.Command{
|
|
85
|
+
Use: "create [name]",
|
|
86
|
+
Short: "Create a new user",
|
|
87
|
+
Args: cobra.ExactArgs(1),
|
|
88
|
+
Run: func(cmd *cobra.Command, args []string) {
|
|
89
|
+
name := args[0]
|
|
90
|
+
// Create user
|
|
91
|
+
},
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
func init() {
|
|
95
|
+
userCmd.AddCommand(userListCmd)
|
|
96
|
+
userCmd.AddCommand(userCreateCmd)
|
|
97
|
+
rootCmd.AddCommand(userCmd)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Usage:
|
|
101
|
+
// myapp user list
|
|
102
|
+
// myapp user create john
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### GOL.3.3.1.3: Define Flags with Appropriate Types
|
|
106
|
+
|
|
107
|
+
**Rule**: Use typed flags (string, int, bool) and provide default values.
|
|
108
|
+
|
|
109
|
+
**Severity**: ERROR
|
|
110
|
+
|
|
111
|
+
**Rationale**: Type safety prevents runtime errors and improves user experience.
|
|
112
|
+
|
|
113
|
+
**✅ Good**:
|
|
114
|
+
```go
|
|
115
|
+
var (
|
|
116
|
+
outputFormat string
|
|
117
|
+
verbose bool
|
|
118
|
+
maxResults int
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
var listCmd = &cobra.Command{
|
|
122
|
+
Use: "list",
|
|
123
|
+
Short: "List resources",
|
|
124
|
+
Run: func(cmd *cobra.Command, args []string) {
|
|
125
|
+
if verbose {
|
|
126
|
+
fmt.Println("Verbose mode enabled")
|
|
127
|
+
}
|
|
128
|
+
fmt.Printf("Output format: %s, Max results: %d\n", outputFormat, maxResults)
|
|
129
|
+
},
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
func init() {
|
|
133
|
+
// String flag with default
|
|
134
|
+
listCmd.Flags().StringVarP(&outputFormat, "output", "o", "table", "Output format (table, json, yaml)")
|
|
135
|
+
|
|
136
|
+
// Boolean flag
|
|
137
|
+
listCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "Enable verbose output")
|
|
138
|
+
|
|
139
|
+
// Integer flag with default
|
|
140
|
+
listCmd.Flags().IntVarP(&maxResults, "limit", "l", 10, "Maximum number of results")
|
|
141
|
+
|
|
142
|
+
// Required flag
|
|
143
|
+
listCmd.MarkFlagRequired("output")
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### GOL.3.3.1.4: Validate Arguments and Flags
|
|
148
|
+
|
|
149
|
+
**Rule**: Validate command arguments and flags before execution.
|
|
150
|
+
|
|
151
|
+
**Severity**: ERROR
|
|
152
|
+
|
|
153
|
+
**Rationale**: Early validation provides clear error messages and prevents invalid operations.
|
|
154
|
+
|
|
155
|
+
**✅ Good**:
|
|
156
|
+
```go
|
|
157
|
+
var createCmd = &cobra.Command{
|
|
158
|
+
Use: "create [name]",
|
|
159
|
+
Short: "Create a resource",
|
|
160
|
+
Args: cobra.ExactArgs(1),
|
|
161
|
+
PreRunE: func(cmd *cobra.Command, args []string) error {
|
|
162
|
+
// Validate name
|
|
163
|
+
name := args[0]
|
|
164
|
+
if len(name) < 3 {
|
|
165
|
+
return fmt.Errorf("name must be at least 3 characters")
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Validate flag
|
|
169
|
+
if outputFormat != "json" && outputFormat != "yaml" {
|
|
170
|
+
return fmt.Errorf("invalid output format: %s", outputFormat)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return nil
|
|
174
|
+
},
|
|
175
|
+
RunE: func(cmd *cobra.Command, args []string) error {
|
|
176
|
+
name := args[0]
|
|
177
|
+
return createResource(name)
|
|
178
|
+
},
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Cobra built-in validators
|
|
182
|
+
var exactOneArg = &cobra.Command{
|
|
183
|
+
Args: cobra.ExactArgs(1),
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
var minTwoArgs = &cobra.Command{
|
|
187
|
+
Args: cobra.MinimumNArgs(2),
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
var maxThreeArgs = &cobra.Command{
|
|
191
|
+
Args: cobra.MaximumNArgs(3),
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
var rangeArgs = &cobra.Command{
|
|
195
|
+
Args: cobra.RangeArgs(1, 3),
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### GOL.3.3.1.5: Provide Helpful Usage Examples
|
|
200
|
+
|
|
201
|
+
**Rule**: Include usage examples in command help text.
|
|
202
|
+
|
|
203
|
+
**Severity**: WARNING
|
|
204
|
+
|
|
205
|
+
**Rationale**: Examples improve discoverability and reduce user confusion.
|
|
206
|
+
|
|
207
|
+
**✅ Good**:
|
|
208
|
+
```go
|
|
209
|
+
var deployCmd = &cobra.Command{
|
|
210
|
+
Use: "deploy [app-name]",
|
|
211
|
+
Short: "Deploy an application",
|
|
212
|
+
Long: `Deploy an application to the specified environment.
|
|
213
|
+
|
|
214
|
+
The deploy command builds and deploys your application to the target environment.
|
|
215
|
+
It supports multiple deployment strategies and configuration options.`,
|
|
216
|
+
Example: ` # Deploy to production
|
|
217
|
+
myapp deploy myapp --env production
|
|
218
|
+
|
|
219
|
+
# Deploy with custom config
|
|
220
|
+
myapp deploy myapp --env staging --config custom.yaml
|
|
221
|
+
|
|
222
|
+
# Deploy with verbose output
|
|
223
|
+
myapp deploy myapp --env dev -v`,
|
|
224
|
+
Args: cobra.ExactArgs(1),
|
|
225
|
+
RunE: func(cmd *cobra.Command, args []string) error {
|
|
226
|
+
appName := args[0]
|
|
227
|
+
return deployApp(appName)
|
|
228
|
+
},
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### GOL.3.3.1.6: Use Persistent Flags for Global Options
|
|
233
|
+
|
|
234
|
+
**Rule**: Use persistent flags for options that apply to all subcommands.
|
|
235
|
+
|
|
236
|
+
**Severity**: INFO
|
|
237
|
+
|
|
238
|
+
**✅ Good**:
|
|
239
|
+
```go
|
|
240
|
+
var (
|
|
241
|
+
configFile string
|
|
242
|
+
verbose bool
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
func init() {
|
|
246
|
+
// Persistent flags available to all subcommands
|
|
247
|
+
rootCmd.PersistentFlags().StringVar(&configFile, "config", "", "config file (default is $HOME/.myapp.yaml)")
|
|
248
|
+
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose output")
|
|
249
|
+
|
|
250
|
+
// Local flags only for this command
|
|
251
|
+
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Usage:
|
|
255
|
+
// myapp --verbose user list # verbose applies to all commands
|
|
256
|
+
// myapp user list --verbose # also works
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## References
|
|
260
|
+
|
|
261
|
+
- [Cobra Documentation](https://github.com/spf13/cobra)
|
|
262
|
+
- [CLI Best Practices](https://clig.dev/)
|
|
263
|
+
- [POSIX Utility Conventions](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html)
|
|
264
|
+
|