specweave 0.18.1 → 0.20.1
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/CLAUDE.md +229 -1817
- package/README.md +68 -0
- package/bin/specweave.js +62 -6
- package/dist/plugins/specweave/lib/hooks/sync-living-docs.d.ts.map +1 -1
- package/dist/plugins/specweave/lib/hooks/sync-living-docs.js +3 -0
- package/dist/plugins/specweave/lib/hooks/sync-living-docs.js.map +1 -1
- package/dist/plugins/specweave/lib/hooks/update-ac-status.d.ts +21 -0
- package/dist/plugins/specweave/lib/hooks/update-ac-status.d.ts.map +1 -0
- package/dist/plugins/specweave/lib/hooks/update-ac-status.js +162 -0
- package/dist/plugins/specweave/lib/hooks/update-ac-status.js.map +1 -0
- package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.js +65 -6
- package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/completion-calculator.d.ts +112 -0
- package/dist/plugins/specweave-github/lib/completion-calculator.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/completion-calculator.js +301 -0
- package/dist/plugins/specweave-github/lib/completion-calculator.js.map +1 -0
- package/dist/plugins/specweave-github/lib/duplicate-detector.d.ts +3 -3
- package/dist/plugins/specweave-github/lib/duplicate-detector.js +3 -3
- package/dist/plugins/specweave-github/lib/epic-content-builder.d.ts +7 -0
- package/dist/plugins/specweave-github/lib/epic-content-builder.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/epic-content-builder.js +42 -0
- package/dist/plugins/specweave-github/lib/epic-content-builder.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts +14 -0
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.js +51 -0
- package/dist/plugins/specweave-github/lib/github-client-v2.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-epic-sync.js +1 -1
- package/dist/plugins/specweave-github/lib/github-epic-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-feature-sync.d.ts +87 -0
- package/dist/plugins/specweave-github/lib/github-feature-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/github-feature-sync.js +412 -0
- package/dist/plugins/specweave-github/lib/github-feature-sync.js.map +1 -0
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.js +64 -13
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/progress-comment-builder.d.ts +78 -0
- package/dist/plugins/specweave-github/lib/progress-comment-builder.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/progress-comment-builder.js +237 -0
- package/dist/plugins/specweave-github/lib/progress-comment-builder.js.map +1 -0
- package/dist/plugins/specweave-github/lib/user-story-content-builder.d.ts +97 -0
- package/dist/plugins/specweave-github/lib/user-story-content-builder.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/user-story-content-builder.js +301 -0
- package/dist/plugins/specweave-github/lib/user-story-content-builder.js.map +1 -0
- package/dist/plugins/specweave-github/lib/user-story-issue-builder.d.ts +83 -0
- package/dist/plugins/specweave-github/lib/user-story-issue-builder.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/user-story-issue-builder.js +386 -0
- package/dist/plugins/specweave-github/lib/user-story-issue-builder.js.map +1 -0
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.d.ts +8 -6
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.js +78 -117
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.js.map +1 -1
- package/dist/src/cli/commands/import-docs.js +4 -4
- package/dist/src/cli/commands/import-docs.js.map +1 -1
- package/dist/src/cli/commands/init-multiproject.d.ts.map +1 -1
- package/dist/src/cli/commands/init-multiproject.js +17 -18
- package/dist/src/cli/commands/init-multiproject.js.map +1 -1
- package/dist/src/cli/commands/migrate-to-multiproject.d.ts.map +1 -1
- package/dist/src/cli/commands/migrate-to-multiproject.js +8 -4
- package/dist/src/cli/commands/migrate-to-multiproject.js.map +1 -1
- package/dist/src/cli/commands/switch-project.d.ts.map +1 -1
- package/dist/src/cli/commands/switch-project.js +9 -26
- package/dist/src/cli/commands/switch-project.js.map +1 -1
- package/dist/src/cli/commands/sync-spec-content.js +3 -0
- package/dist/src/cli/commands/sync-spec-content.js.map +1 -1
- package/dist/src/core/deduplication/command-deduplicator.d.ts +166 -0
- package/dist/src/core/deduplication/command-deduplicator.d.ts.map +1 -0
- package/dist/src/core/deduplication/command-deduplicator.js +254 -0
- package/dist/src/core/deduplication/command-deduplicator.js.map +1 -0
- package/dist/src/core/increment/active-increment-manager.d.ts +42 -15
- package/dist/src/core/increment/active-increment-manager.d.ts.map +1 -1
- package/dist/src/core/increment/active-increment-manager.js +113 -46
- package/dist/src/core/increment/active-increment-manager.js.map +1 -1
- package/dist/src/core/increment/conflict-resolver.d.ts +40 -0
- package/dist/src/core/increment/conflict-resolver.d.ts.map +1 -0
- package/dist/src/core/increment/conflict-resolver.js +219 -0
- package/dist/src/core/increment/conflict-resolver.js.map +1 -0
- package/dist/src/core/increment/discipline-checker.d.ts.map +1 -1
- package/dist/src/core/increment/discipline-checker.js +7 -1
- package/dist/src/core/increment/discipline-checker.js.map +1 -1
- package/dist/src/core/increment/duplicate-detector.d.ts +52 -0
- package/dist/src/core/increment/duplicate-detector.d.ts.map +1 -0
- package/dist/src/core/increment/duplicate-detector.js +276 -0
- package/dist/src/core/increment/duplicate-detector.js.map +1 -0
- package/dist/src/core/increment/increment-archiver.d.ts +90 -0
- package/dist/src/core/increment/increment-archiver.d.ts.map +1 -0
- package/dist/src/core/increment/increment-archiver.js +368 -0
- package/dist/src/core/increment/increment-archiver.js.map +1 -0
- package/dist/src/core/increment/increment-reopener.d.ts +165 -0
- package/dist/src/core/increment/increment-reopener.d.ts.map +1 -0
- package/dist/src/core/increment/increment-reopener.js +390 -0
- package/dist/src/core/increment/increment-reopener.js.map +1 -0
- package/dist/src/core/increment/metadata-manager.d.ts +26 -1
- package/dist/src/core/increment/metadata-manager.d.ts.map +1 -1
- package/dist/src/core/increment/metadata-manager.js +143 -5
- package/dist/src/core/increment/metadata-manager.js.map +1 -1
- package/dist/src/core/increment/recent-work-scanner.d.ts +121 -0
- package/dist/src/core/increment/recent-work-scanner.d.ts.map +1 -0
- package/dist/src/core/increment/recent-work-scanner.js +303 -0
- package/dist/src/core/increment/recent-work-scanner.js.map +1 -0
- package/dist/src/core/increment/types.d.ts +1 -0
- package/dist/src/core/increment/types.d.ts.map +1 -1
- package/dist/src/core/increment-utils.d.ts +112 -0
- package/dist/src/core/increment-utils.d.ts.map +1 -0
- package/dist/src/core/increment-utils.js +210 -0
- package/dist/src/core/increment-utils.js.map +1 -0
- package/dist/src/core/living-docs/ac-project-specific-generator.d.ts +65 -0
- package/dist/src/core/living-docs/ac-project-specific-generator.d.ts.map +1 -0
- package/dist/src/core/living-docs/ac-project-specific-generator.js +175 -0
- package/dist/src/core/living-docs/ac-project-specific-generator.js.map +1 -0
- package/dist/src/core/living-docs/feature-archiver.d.ts +130 -0
- package/dist/src/core/living-docs/feature-archiver.d.ts.map +1 -0
- package/dist/src/core/living-docs/feature-archiver.js +549 -0
- package/dist/src/core/living-docs/feature-archiver.js.map +1 -0
- package/dist/src/core/living-docs/feature-id-manager.d.ts +81 -0
- package/dist/src/core/living-docs/feature-id-manager.d.ts.map +1 -0
- package/dist/src/core/living-docs/feature-id-manager.js +339 -0
- package/dist/src/core/living-docs/feature-id-manager.js.map +1 -0
- package/dist/src/core/living-docs/hierarchy-mapper.d.ts +144 -83
- package/dist/src/core/living-docs/hierarchy-mapper.d.ts.map +1 -1
- package/dist/src/core/living-docs/hierarchy-mapper.js +488 -270
- package/dist/src/core/living-docs/hierarchy-mapper.js.map +1 -1
- package/dist/src/core/living-docs/index.d.ts +6 -0
- package/dist/src/core/living-docs/index.d.ts.map +1 -1
- package/dist/src/core/living-docs/index.js +6 -0
- package/dist/src/core/living-docs/index.js.map +1 -1
- package/dist/src/core/living-docs/project-detector.d.ts +6 -0
- package/dist/src/core/living-docs/project-detector.d.ts.map +1 -1
- package/dist/src/core/living-docs/project-detector.js +35 -1
- package/dist/src/core/living-docs/project-detector.js.map +1 -1
- package/dist/src/core/living-docs/spec-distributor.d.ts +100 -26
- package/dist/src/core/living-docs/spec-distributor.d.ts.map +1 -1
- package/dist/src/core/living-docs/spec-distributor.js +1275 -258
- package/dist/src/core/living-docs/spec-distributor.js.map +1 -1
- package/dist/src/core/living-docs/task-project-specific-generator.d.ts +109 -0
- package/dist/src/core/living-docs/task-project-specific-generator.d.ts.map +1 -0
- package/dist/src/core/living-docs/task-project-specific-generator.js +221 -0
- package/dist/src/core/living-docs/task-project-specific-generator.js.map +1 -0
- package/dist/src/core/living-docs/types.d.ts +143 -0
- package/dist/src/core/living-docs/types.d.ts.map +1 -1
- package/dist/src/core/project-manager.d.ts +2 -17
- package/dist/src/core/project-manager.d.ts.map +1 -1
- package/dist/src/core/project-manager.js +68 -48
- package/dist/src/core/project-manager.js.map +1 -1
- package/dist/src/core/spec-content-sync.d.ts +1 -1
- package/dist/src/core/spec-content-sync.d.ts.map +1 -1
- package/dist/src/core/sync/enhanced-content-builder.d.ts.map +1 -1
- package/dist/src/core/sync/enhanced-content-builder.js +2 -1
- package/dist/src/core/sync/enhanced-content-builder.js.map +1 -1
- package/dist/src/core/sync/performance-optimizer.d.ts +153 -0
- package/dist/src/core/sync/performance-optimizer.d.ts.map +1 -0
- package/dist/src/core/sync/performance-optimizer.js +220 -0
- package/dist/src/core/sync/performance-optimizer.js.map +1 -0
- package/dist/src/core/sync/retry-handler.d.ts +98 -0
- package/dist/src/core/sync/retry-handler.d.ts.map +1 -0
- package/dist/src/core/sync/retry-handler.js +196 -0
- package/dist/src/core/sync/retry-handler.js.map +1 -0
- package/dist/src/core/types/config.d.ts +94 -0
- package/dist/src/core/types/config.d.ts.map +1 -1
- package/dist/src/core/types/config.js +16 -0
- package/dist/src/core/types/config.js.map +1 -1
- package/dist/src/core/types/increment-metadata.d.ts +6 -0
- package/dist/src/core/types/increment-metadata.d.ts.map +1 -1
- package/dist/src/core/types/increment-metadata.js +10 -1
- package/dist/src/core/types/increment-metadata.js.map +1 -1
- package/dist/src/integrations/jira/jira-incremental-mapper.d.ts.map +1 -1
- package/dist/src/integrations/jira/jira-incremental-mapper.js +4 -8
- package/dist/src/integrations/jira/jira-incremental-mapper.js.map +1 -1
- package/dist/src/integrations/jira/jira-mapper.d.ts.map +1 -1
- package/dist/src/integrations/jira/jira-mapper.js +4 -8
- package/dist/src/integrations/jira/jira-mapper.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/COMMANDS.md +13 -4
- package/plugins/specweave/commands/specweave-abandon.md +22 -20
- package/plugins/specweave/commands/specweave-archive-features.md +121 -0
- package/plugins/specweave/commands/specweave-archive-increments.md +82 -0
- package/plugins/specweave/commands/specweave-archive.md +363 -0
- package/plugins/specweave/commands/specweave-backlog.md +211 -0
- package/plugins/specweave/commands/specweave-fix-duplicates.md +517 -0
- package/plugins/specweave/commands/specweave-increment.md +4 -3
- package/plugins/specweave/commands/specweave-progress.md +176 -27
- package/plugins/specweave/commands/specweave-reopen.md +391 -0
- package/plugins/specweave/commands/specweave-restore-feature.md +90 -0
- package/plugins/specweave/commands/specweave-restore.md +309 -0
- package/plugins/specweave/commands/specweave-resume.md +51 -23
- package/plugins/specweave/commands/specweave-status.md +41 -7
- package/plugins/specweave/commands/specweave-sync-specs.md +425 -0
- package/plugins/specweave/hooks/hooks.json +4 -0
- package/plugins/specweave/hooks/lib/sync-spec-content.sh +2 -2
- package/plugins/specweave/hooks/post-task-completion.sh +39 -0
- package/plugins/specweave/hooks/pre-command-deduplication.sh +83 -0
- package/plugins/specweave/hooks/user-prompt-submit.sh +1 -1
- package/plugins/specweave/lib/hooks/sync-living-docs.js +2 -0
- package/plugins/specweave/lib/hooks/sync-living-docs.ts +4 -0
- package/plugins/specweave/lib/hooks/update-ac-status.js +102 -0
- package/plugins/specweave/lib/hooks/update-ac-status.ts +192 -0
- package/plugins/specweave/skills/archive-increments/SKILL.md +198 -0
- package/plugins/specweave/skills/increment-planner/scripts/feature-utils.js +14 -0
- package/plugins/specweave/skills/smart-reopen-detector/SKILL.md +244 -0
- package/plugins/specweave-ado/lib/ado-spec-content-sync.js +49 -5
- package/plugins/specweave-ado/lib/ado-spec-content-sync.ts +72 -6
- package/plugins/specweave-confluent/.claude-plugin/plugin.json +23 -0
- package/plugins/specweave-confluent/README.md +375 -0
- package/plugins/specweave-confluent/agents/confluent-architect/AGENT.md +306 -0
- package/plugins/specweave-confluent/skills/confluent-kafka-connect/SKILL.md +453 -0
- package/plugins/specweave-confluent/skills/confluent-ksqldb/SKILL.md +470 -0
- package/plugins/specweave-confluent/skills/confluent-schema-registry/SKILL.md +316 -0
- package/plugins/specweave-github/agents/github-task-splitter/AGENT.md +2 -2
- package/plugins/specweave-github/agents/user-story-updater/AGENT.md +148 -0
- package/plugins/specweave-github/commands/specweave-github-cleanup-duplicates.md +1 -1
- package/plugins/specweave-github/commands/specweave-github-update-user-story.md +156 -0
- package/plugins/specweave-github/hooks/post-task-completion.sh +10 -9
- package/plugins/specweave-github/lib/completion-calculator.js +262 -0
- package/plugins/specweave-github/lib/completion-calculator.ts +434 -0
- package/plugins/specweave-github/lib/duplicate-detector.js +3 -3
- package/plugins/specweave-github/lib/duplicate-detector.ts +4 -4
- package/plugins/specweave-github/lib/epic-content-builder.js +38 -0
- package/plugins/specweave-github/lib/epic-content-builder.ts +59 -0
- package/plugins/specweave-github/lib/github-client-v2.js +49 -0
- package/plugins/specweave-github/lib/github-client-v2.ts +59 -0
- package/plugins/specweave-github/lib/github-epic-sync.ts +1 -1
- package/plugins/specweave-github/lib/github-feature-sync.js +381 -0
- package/plugins/specweave-github/lib/github-feature-sync.ts +568 -0
- package/plugins/specweave-github/lib/github-spec-content-sync.js +40 -10
- package/plugins/specweave-github/lib/github-spec-content-sync.ts +82 -14
- package/plugins/specweave-github/lib/progress-comment-builder.js +229 -0
- package/plugins/specweave-github/lib/progress-comment-builder.ts +324 -0
- package/plugins/specweave-github/lib/user-story-content-builder.js +299 -0
- package/plugins/specweave-github/lib/user-story-content-builder.ts +413 -0
- package/plugins/specweave-github/lib/user-story-issue-builder.js +344 -0
- package/plugins/specweave-github/lib/user-story-issue-builder.ts +543 -0
- package/plugins/specweave-github/skills/github-issue-standard/SKILL.md +189 -0
- package/plugins/{specweave-ado/lib/enhanced-ado-sync.js → specweave-jira/lib/enhanced-jira-sync.js} +25 -61
- package/plugins/specweave-jira/lib/{enhanced-jira-sync.ts.disabled → enhanced-jira-sync.ts} +26 -52
- package/plugins/specweave-kafka/.claude-plugin/plugin.json +26 -0
- package/plugins/specweave-kafka/IMPLEMENTATION-COMPLETE.md +483 -0
- package/plugins/specweave-kafka/README.md +242 -0
- package/plugins/specweave-kafka/agents/kafka-architect/AGENT.md +235 -0
- package/plugins/specweave-kafka/agents/kafka-devops/AGENT.md +209 -0
- package/plugins/specweave-kafka/agents/kafka-observability/AGENT.md +266 -0
- package/plugins/specweave-kafka/commands/deploy.md +99 -0
- package/plugins/specweave-kafka/commands/dev-env.md +176 -0
- package/plugins/specweave-kafka/commands/mcp-configure.md +101 -0
- package/plugins/specweave-kafka/commands/monitor-setup.md +96 -0
- package/plugins/specweave-kafka/docker/kafka-local/docker-compose.yml +187 -0
- package/plugins/specweave-kafka/docker/redpanda/docker-compose.yml +199 -0
- package/plugins/specweave-kafka/docker/templates/consumer-nodejs.js +225 -0
- package/plugins/specweave-kafka/docker/templates/consumer-python.py +220 -0
- package/plugins/specweave-kafka/docker/templates/producer-nodejs.js +168 -0
- package/plugins/specweave-kafka/docker/templates/producer-python.py +167 -0
- package/plugins/specweave-kafka/lib/adapters/apache-kafka-adapter.js +438 -0
- package/plugins/specweave-kafka/lib/adapters/apache-kafka-adapter.ts +541 -0
- package/plugins/specweave-kafka/lib/adapters/platform-adapter.js +47 -0
- package/plugins/specweave-kafka/lib/adapters/platform-adapter.ts +343 -0
- package/plugins/specweave-kafka/lib/cli/kcat-wrapper.js +258 -0
- package/plugins/specweave-kafka/lib/cli/kcat-wrapper.ts +298 -0
- package/plugins/specweave-kafka/lib/cli/types.js +10 -0
- package/plugins/specweave-kafka/lib/cli/types.ts +92 -0
- package/plugins/specweave-kafka/lib/connectors/connector-catalog.js +305 -0
- package/plugins/specweave-kafka/lib/connectors/connector-catalog.ts +528 -0
- package/plugins/specweave-kafka/lib/documentation/diagram-generator.js +114 -0
- package/plugins/specweave-kafka/lib/documentation/diagram-generator.ts +195 -0
- package/plugins/specweave-kafka/lib/documentation/exporter.js +210 -0
- package/plugins/specweave-kafka/lib/documentation/exporter.ts +338 -0
- package/plugins/specweave-kafka/lib/documentation/schema-catalog-generator.js +60 -0
- package/plugins/specweave-kafka/lib/documentation/schema-catalog-generator.ts +130 -0
- package/plugins/specweave-kafka/lib/documentation/topology-generator.js +143 -0
- package/plugins/specweave-kafka/lib/documentation/topology-generator.ts +290 -0
- package/plugins/specweave-kafka/lib/mcp/detector.js +298 -0
- package/plugins/specweave-kafka/lib/mcp/detector.ts +352 -0
- package/plugins/specweave-kafka/lib/mcp/types.js +21 -0
- package/plugins/specweave-kafka/lib/mcp/types.ts +77 -0
- package/plugins/specweave-kafka/lib/multi-cluster/cluster-config-manager.js +193 -0
- package/plugins/specweave-kafka/lib/multi-cluster/cluster-config-manager.ts +362 -0
- package/plugins/specweave-kafka/lib/multi-cluster/cluster-switcher.js +188 -0
- package/plugins/specweave-kafka/lib/multi-cluster/cluster-switcher.ts +359 -0
- package/plugins/specweave-kafka/lib/multi-cluster/health-aggregator.js +195 -0
- package/plugins/specweave-kafka/lib/multi-cluster/health-aggregator.ts +380 -0
- package/plugins/specweave-kafka/lib/observability/opentelemetry-kafka.js +209 -0
- package/plugins/specweave-kafka/lib/observability/opentelemetry-kafka.ts +358 -0
- package/plugins/specweave-kafka/lib/patterns/advanced-ksqldb-patterns.js +354 -0
- package/plugins/specweave-kafka/lib/patterns/advanced-ksqldb-patterns.ts +563 -0
- package/plugins/specweave-kafka/lib/patterns/circuit-breaker-resilience.js +259 -0
- package/plugins/specweave-kafka/lib/patterns/circuit-breaker-resilience.ts +516 -0
- package/plugins/specweave-kafka/lib/patterns/dead-letter-queue.js +233 -0
- package/plugins/specweave-kafka/lib/patterns/dead-letter-queue.ts +423 -0
- package/plugins/specweave-kafka/lib/patterns/exactly-once-semantics.js +266 -0
- package/plugins/specweave-kafka/lib/patterns/exactly-once-semantics.ts +445 -0
- package/plugins/specweave-kafka/lib/patterns/flink-kafka-integration.js +312 -0
- package/plugins/specweave-kafka/lib/patterns/flink-kafka-integration.ts +561 -0
- package/plugins/specweave-kafka/lib/patterns/multi-dc-replication.js +289 -0
- package/plugins/specweave-kafka/lib/patterns/multi-dc-replication.ts +607 -0
- package/plugins/specweave-kafka/lib/patterns/rate-limiting-backpressure.js +264 -0
- package/plugins/specweave-kafka/lib/patterns/rate-limiting-backpressure.ts +498 -0
- package/plugins/specweave-kafka/lib/patterns/stream-processing-optimization.js +263 -0
- package/plugins/specweave-kafka/lib/patterns/stream-processing-optimization.ts +549 -0
- package/plugins/specweave-kafka/lib/patterns/tiered-storage-compaction.js +205 -0
- package/plugins/specweave-kafka/lib/patterns/tiered-storage-compaction.ts +399 -0
- package/plugins/specweave-kafka/lib/performance/performance-optimizer.js +249 -0
- package/plugins/specweave-kafka/lib/performance/performance-optimizer.ts +427 -0
- package/plugins/specweave-kafka/lib/security/kafka-security.js +252 -0
- package/plugins/specweave-kafka/lib/security/kafka-security.ts +494 -0
- package/plugins/specweave-kafka/lib/utils/capacity-planner.js +203 -0
- package/plugins/specweave-kafka/lib/utils/capacity-planner.ts +469 -0
- package/plugins/specweave-kafka/lib/utils/config-validator.js +419 -0
- package/plugins/specweave-kafka/lib/utils/config-validator.ts +564 -0
- package/plugins/specweave-kafka/lib/utils/partitioning.js +329 -0
- package/plugins/specweave-kafka/lib/utils/partitioning.ts +473 -0
- package/plugins/specweave-kafka/lib/utils/sizing.js +221 -0
- package/plugins/specweave-kafka/lib/utils/sizing.ts +374 -0
- package/plugins/specweave-kafka/monitoring/grafana/dashboards/kafka-broker-metrics.json +628 -0
- package/plugins/specweave-kafka/monitoring/grafana/dashboards/kafka-cluster-overview.json +564 -0
- package/plugins/specweave-kafka/monitoring/grafana/dashboards/kafka-consumer-lag.json +509 -0
- package/plugins/specweave-kafka/monitoring/grafana/dashboards/kafka-jvm-metrics.json +674 -0
- package/plugins/specweave-kafka/monitoring/grafana/dashboards/kafka-topic-metrics.json +578 -0
- package/plugins/specweave-kafka/monitoring/grafana/provisioning/dashboards/kafka.yml +17 -0
- package/plugins/specweave-kafka/monitoring/grafana/provisioning/datasources/prometheus.yml +17 -0
- package/plugins/specweave-kafka/monitoring/prometheus/kafka-alerts.yml +415 -0
- package/plugins/specweave-kafka/monitoring/prometheus/kafka-jmx-exporter.yml +256 -0
- package/plugins/specweave-kafka/package.json +41 -0
- package/plugins/specweave-kafka/skills/kafka-architecture/SKILL.md +647 -0
- package/plugins/specweave-kafka/skills/kafka-cli-tools/SKILL.md +433 -0
- package/plugins/specweave-kafka/skills/kafka-iac-deployment/SKILL.md +449 -0
- package/plugins/specweave-kafka/skills/kafka-kubernetes/SKILL.md +667 -0
- package/plugins/specweave-kafka/skills/kafka-mcp-integration/SKILL.md +273 -0
- package/plugins/specweave-kafka/skills/kafka-observability/SKILL.md +576 -0
- package/plugins/specweave-kafka/templates/config/broker-production.properties +254 -0
- package/plugins/specweave-kafka/templates/config/consumer-low-latency.properties +112 -0
- package/plugins/specweave-kafka/templates/config/producer-high-throughput.properties +120 -0
- package/plugins/specweave-kafka/templates/migration/mirrormaker2-config.properties +234 -0
- package/plugins/specweave-kafka/templates/monitoring/grafana/multi-cluster-dashboard.json +686 -0
- package/plugins/specweave-kafka/terraform/apache-kafka/main.tf +347 -0
- package/plugins/specweave-kafka/terraform/apache-kafka/outputs.tf +107 -0
- package/plugins/specweave-kafka/terraform/apache-kafka/templates/kafka-broker-init.sh.tpl +216 -0
- package/plugins/specweave-kafka/terraform/apache-kafka/variables.tf +156 -0
- package/plugins/specweave-kafka/terraform/aws-msk/main.tf +362 -0
- package/plugins/specweave-kafka/terraform/aws-msk/outputs.tf +93 -0
- package/plugins/specweave-kafka/terraform/aws-msk/templates/server.properties.tpl +32 -0
- package/plugins/specweave-kafka/terraform/aws-msk/variables.tf +235 -0
- package/plugins/specweave-kafka/terraform/azure-event-hubs/main.tf +281 -0
- package/plugins/specweave-kafka/terraform/azure-event-hubs/outputs.tf +118 -0
- package/plugins/specweave-kafka/terraform/azure-event-hubs/variables.tf +148 -0
- package/plugins/specweave-kafka/tsconfig.json +21 -0
- package/plugins/specweave-kafka-streams/.claude-plugin/plugin.json +23 -0
- package/plugins/specweave-kafka-streams/README.md +310 -0
- package/plugins/specweave-kafka-streams/skills/kafka-streams-topology/SKILL.md +539 -0
- package/plugins/specweave-n8n/.claude-plugin/plugin.json +22 -0
- package/plugins/specweave-n8n/README.md +354 -0
- package/plugins/specweave-n8n/skills/n8n-kafka-workflows/SKILL.md +504 -0
- package/plugins/specweave-release/commands/specweave-release-platform.md +1 -1
- package/plugins/specweave-release/hooks/post-task-completion.sh +2 -2
- package/src/templates/AGENTS.md.template +601 -7
- package/src/templates/CLAUDE.md.template +188 -88
- package/dist/locales/de/.gitkeep +0 -0
- package/dist/locales/de/cli.json +0 -108
- package/dist/locales/en/cli.json +0 -287
- package/dist/locales/en/errors.json +0 -7
- package/dist/locales/en/templates.json +0 -6
- package/dist/locales/es/.gitkeep +0 -0
- package/dist/locales/es/cli.json +0 -41
- package/dist/locales/fr/.gitkeep +0 -0
- package/dist/locales/fr/cli.json +0 -108
- package/dist/locales/ja/.gitkeep +0 -0
- package/dist/locales/ja/cli.json +0 -108
- package/dist/locales/ko/.gitkeep +0 -0
- package/dist/locales/ko/cli.json +0 -108
- package/dist/locales/pt/.gitkeep +0 -0
- package/dist/locales/pt/cli.json +0 -108
- package/dist/locales/ru/.gitkeep +0 -0
- package/dist/locales/ru/cli.json +0 -269
- package/dist/locales/zh/.gitkeep +0 -0
- package/dist/locales/zh/cli.json +0 -108
- package/dist/plugins/specweave-ado/lib/enhanced-ado-sync.d.ts +0 -25
- package/dist/plugins/specweave-ado/lib/enhanced-ado-sync.d.ts.map +0 -1
- package/dist/plugins/specweave-ado/lib/enhanced-ado-sync.js +0 -191
- package/dist/plugins/specweave-ado/lib/enhanced-ado-sync.js.map +0 -1
- package/dist/spec-parser.js +0 -629
- package/dist/src/core/sync/spec-content-sync.d.ts +0 -88
- package/dist/src/core/sync/spec-content-sync.d.ts.map +0 -1
- package/dist/src/core/sync/spec-content-sync.js +0 -5
- package/dist/src/core/sync/spec-content-sync.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/plugins/specweave-ado/commands/specweave-ado-sync-spec.md +0 -255
- package/plugins/specweave-github/commands/specweave-github-sync-epic.md +0 -248
- package/plugins/specweave-github/commands/specweave-github-sync-from.md +0 -147
- package/plugins/specweave-github/commands/specweave-github-sync-spec.md +0 -208
- package/plugins/specweave-github/commands/specweave-github-sync-tasks.md +0 -530
- package/plugins/specweave-jira/commands/specweave-jira-sync-epic.md +0 -267
- package/plugins/specweave-jira/commands/specweave-jira-sync-spec.md +0 -240
|
@@ -0,0 +1,607 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-DC Replication Patterns for Kafka
|
|
3
|
+
*
|
|
4
|
+
* MirrorMaker 2, Cluster Linking, Active-Active and Active-Passive setups
|
|
5
|
+
*
|
|
6
|
+
* @module multi-dc-replication
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Replication Topology Types
|
|
11
|
+
*/
|
|
12
|
+
export enum ReplicationTopology {
|
|
13
|
+
/** One-way replication (DR scenario) */
|
|
14
|
+
ACTIVE_PASSIVE = 'active-passive',
|
|
15
|
+
/** Bidirectional replication (multi-region writes) */
|
|
16
|
+
ACTIVE_ACTIVE = 'active-active',
|
|
17
|
+
/** Hub-and-spoke pattern (central aggregation) */
|
|
18
|
+
HUB_SPOKE = 'hub-spoke',
|
|
19
|
+
/** Fan-out pattern (distribution to multiple regions) */
|
|
20
|
+
FAN_OUT = 'fan-out',
|
|
21
|
+
/** Aggregation pattern (collection from multiple regions) */
|
|
22
|
+
AGGREGATION = 'aggregation',
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Replication Strategy
|
|
27
|
+
*/
|
|
28
|
+
export enum ReplicationStrategy {
|
|
29
|
+
/** Confluent MirrorMaker 2 (recommended) */
|
|
30
|
+
MIRROR_MAKER_2 = 'mirrormaker2',
|
|
31
|
+
/** Confluent Cluster Linking (premium feature) */
|
|
32
|
+
CLUSTER_LINKING = 'cluster-linking',
|
|
33
|
+
/** Legacy MirrorMaker 1 (deprecated) */
|
|
34
|
+
MIRROR_MAKER_1 = 'mirrormaker1',
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Data Center Configuration
|
|
39
|
+
*/
|
|
40
|
+
export interface DataCenterConfig {
|
|
41
|
+
/** DC identifier */
|
|
42
|
+
id: string;
|
|
43
|
+
/** DC display name */
|
|
44
|
+
name: string;
|
|
45
|
+
/** Region (e.g., us-east-1, eu-west-1) */
|
|
46
|
+
region: string;
|
|
47
|
+
/** Kafka bootstrap servers */
|
|
48
|
+
bootstrapServers: string[];
|
|
49
|
+
/** Is this the primary DC? */
|
|
50
|
+
primary?: boolean;
|
|
51
|
+
/** Latency to other DCs in ms */
|
|
52
|
+
latencyMs?: Record<string, number>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Replication Flow Configuration
|
|
57
|
+
*/
|
|
58
|
+
export interface ReplicationFlowConfig {
|
|
59
|
+
/** Source data center */
|
|
60
|
+
source: DataCenterConfig;
|
|
61
|
+
/** Target data center */
|
|
62
|
+
target: DataCenterConfig;
|
|
63
|
+
/** Topics to replicate (regex patterns supported) */
|
|
64
|
+
topics: string[];
|
|
65
|
+
/** Topic rename pattern (optional) */
|
|
66
|
+
renamePattern?: {
|
|
67
|
+
from: string;
|
|
68
|
+
to: string;
|
|
69
|
+
};
|
|
70
|
+
/** Replication factor at target */
|
|
71
|
+
replicationFactor?: number;
|
|
72
|
+
/** Enable exactly-once semantics */
|
|
73
|
+
exactlyOnce?: boolean;
|
|
74
|
+
/** Consumer group offset sync */
|
|
75
|
+
syncConsumerOffsets?: boolean;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* MirrorMaker 2 Configuration
|
|
80
|
+
*/
|
|
81
|
+
export interface MirrorMaker2Config {
|
|
82
|
+
/** Replication flows */
|
|
83
|
+
flows: ReplicationFlowConfig[];
|
|
84
|
+
/** Offset sync interval in seconds */
|
|
85
|
+
offsetSyncIntervalSec?: number;
|
|
86
|
+
/** Checkpoint sync interval in seconds */
|
|
87
|
+
checkpointSyncIntervalSec?: number;
|
|
88
|
+
/** Enable heartbeats */
|
|
89
|
+
enableHeartbeats?: boolean;
|
|
90
|
+
/** Heartbeat interval in seconds */
|
|
91
|
+
heartbeatIntervalSec?: number;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Cluster Linking Configuration (Confluent)
|
|
96
|
+
*/
|
|
97
|
+
export interface ClusterLinkingConfig {
|
|
98
|
+
/** Link name */
|
|
99
|
+
linkName: string;
|
|
100
|
+
/** Source cluster */
|
|
101
|
+
source: DataCenterConfig;
|
|
102
|
+
/** Destination cluster */
|
|
103
|
+
destination: DataCenterConfig;
|
|
104
|
+
/** Link mode */
|
|
105
|
+
mode: 'SOURCE' | 'DESTINATION';
|
|
106
|
+
/** Mirror topics */
|
|
107
|
+
mirrorTopics: string[];
|
|
108
|
+
/** Enable auto-create mirror topics */
|
|
109
|
+
autoCreateMirrorTopics?: boolean;
|
|
110
|
+
/** Mirror topic prefix */
|
|
111
|
+
mirrorTopicPrefix?: string;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Multi-DC Replication Manager
|
|
116
|
+
*
|
|
117
|
+
* Manages MirrorMaker 2 and Cluster Linking configurations
|
|
118
|
+
*/
|
|
119
|
+
export class MultiDCReplicationManager {
|
|
120
|
+
/**
|
|
121
|
+
* Generate MirrorMaker 2 configuration
|
|
122
|
+
*/
|
|
123
|
+
static generateMirrorMaker2Config(
|
|
124
|
+
topology: ReplicationTopology,
|
|
125
|
+
dataCenters: DataCenterConfig[],
|
|
126
|
+
topics: string[]
|
|
127
|
+
): MirrorMaker2Config {
|
|
128
|
+
const flows: ReplicationFlowConfig[] = [];
|
|
129
|
+
|
|
130
|
+
switch (topology) {
|
|
131
|
+
case ReplicationTopology.ACTIVE_PASSIVE:
|
|
132
|
+
flows.push(...this.createActivePassiveFlows(dataCenters, topics));
|
|
133
|
+
break;
|
|
134
|
+
|
|
135
|
+
case ReplicationTopology.ACTIVE_ACTIVE:
|
|
136
|
+
flows.push(...this.createActiveActiveFlows(dataCenters, topics));
|
|
137
|
+
break;
|
|
138
|
+
|
|
139
|
+
case ReplicationTopology.HUB_SPOKE:
|
|
140
|
+
flows.push(...this.createHubSpokeFlows(dataCenters, topics));
|
|
141
|
+
break;
|
|
142
|
+
|
|
143
|
+
case ReplicationTopology.FAN_OUT:
|
|
144
|
+
flows.push(...this.createFanOutFlows(dataCenters, topics));
|
|
145
|
+
break;
|
|
146
|
+
|
|
147
|
+
case ReplicationTopology.AGGREGATION:
|
|
148
|
+
flows.push(...this.createAggregationFlows(dataCenters, topics));
|
|
149
|
+
break;
|
|
150
|
+
|
|
151
|
+
default:
|
|
152
|
+
throw new Error(`Unsupported topology: ${topology}`);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
flows,
|
|
157
|
+
offsetSyncIntervalSec: 60,
|
|
158
|
+
checkpointSyncIntervalSec: 60,
|
|
159
|
+
enableHeartbeats: true,
|
|
160
|
+
heartbeatIntervalSec: 3,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Create Active-Passive replication flows
|
|
166
|
+
*
|
|
167
|
+
* Primary DC → Standby DC (one-way)
|
|
168
|
+
*/
|
|
169
|
+
private static createActivePassiveFlows(
|
|
170
|
+
dataCenters: DataCenterConfig[],
|
|
171
|
+
topics: string[]
|
|
172
|
+
): ReplicationFlowConfig[] {
|
|
173
|
+
const primary = dataCenters.find((dc) => dc.primary);
|
|
174
|
+
const standby = dataCenters.find((dc) => !dc.primary);
|
|
175
|
+
|
|
176
|
+
if (!primary || !standby) {
|
|
177
|
+
throw new Error('Active-Passive requires exactly 1 primary and 1 standby DC');
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return [
|
|
181
|
+
{
|
|
182
|
+
source: primary,
|
|
183
|
+
target: standby,
|
|
184
|
+
topics,
|
|
185
|
+
replicationFactor: 3,
|
|
186
|
+
exactlyOnce: true,
|
|
187
|
+
syncConsumerOffsets: true,
|
|
188
|
+
},
|
|
189
|
+
];
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Create Active-Active replication flows
|
|
194
|
+
*
|
|
195
|
+
* DC1 ↔ DC2 (bidirectional)
|
|
196
|
+
*/
|
|
197
|
+
private static createActiveActiveFlows(
|
|
198
|
+
dataCenters: DataCenterConfig[],
|
|
199
|
+
topics: string[]
|
|
200
|
+
): ReplicationFlowConfig[] {
|
|
201
|
+
if (dataCenters.length !== 2) {
|
|
202
|
+
throw new Error('Active-Active requires exactly 2 data centers');
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const [dc1, dc2] = dataCenters;
|
|
206
|
+
|
|
207
|
+
return [
|
|
208
|
+
// DC1 → DC2
|
|
209
|
+
{
|
|
210
|
+
source: dc1,
|
|
211
|
+
target: dc2,
|
|
212
|
+
topics,
|
|
213
|
+
renamePattern: {
|
|
214
|
+
from: '(.*)',
|
|
215
|
+
to: `${dc1.id}.$1`,
|
|
216
|
+
},
|
|
217
|
+
replicationFactor: 3,
|
|
218
|
+
exactlyOnce: true,
|
|
219
|
+
syncConsumerOffsets: false, // Not recommended for active-active
|
|
220
|
+
},
|
|
221
|
+
// DC2 → DC1
|
|
222
|
+
{
|
|
223
|
+
source: dc2,
|
|
224
|
+
target: dc1,
|
|
225
|
+
topics,
|
|
226
|
+
renamePattern: {
|
|
227
|
+
from: '(.*)',
|
|
228
|
+
to: `${dc2.id}.$1`,
|
|
229
|
+
},
|
|
230
|
+
replicationFactor: 3,
|
|
231
|
+
exactlyOnce: true,
|
|
232
|
+
syncConsumerOffsets: false,
|
|
233
|
+
},
|
|
234
|
+
];
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Create Hub-Spoke replication flows
|
|
239
|
+
*
|
|
240
|
+
* Spoke1 → Hub, Spoke2 → Hub, Spoke3 → Hub
|
|
241
|
+
*/
|
|
242
|
+
private static createHubSpokeFlows(
|
|
243
|
+
dataCenters: DataCenterConfig[],
|
|
244
|
+
topics: string[]
|
|
245
|
+
): ReplicationFlowConfig[] {
|
|
246
|
+
const hub = dataCenters.find((dc) => dc.primary);
|
|
247
|
+
const spokes = dataCenters.filter((dc) => !dc.primary);
|
|
248
|
+
|
|
249
|
+
if (!hub || spokes.length === 0) {
|
|
250
|
+
throw new Error('Hub-Spoke requires 1 hub (primary) and 1+ spokes');
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return spokes.map((spoke) => ({
|
|
254
|
+
source: spoke,
|
|
255
|
+
target: hub,
|
|
256
|
+
topics,
|
|
257
|
+
renamePattern: {
|
|
258
|
+
from: '(.*)',
|
|
259
|
+
to: `${spoke.id}.$1`,
|
|
260
|
+
},
|
|
261
|
+
replicationFactor: 3,
|
|
262
|
+
exactlyOnce: true,
|
|
263
|
+
syncConsumerOffsets: false,
|
|
264
|
+
}));
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Create Fan-Out replication flows
|
|
269
|
+
*
|
|
270
|
+
* Hub → Spoke1, Hub → Spoke2, Hub → Spoke3
|
|
271
|
+
*/
|
|
272
|
+
private static createFanOutFlows(
|
|
273
|
+
dataCenters: DataCenterConfig[],
|
|
274
|
+
topics: string[]
|
|
275
|
+
): ReplicationFlowConfig[] {
|
|
276
|
+
const hub = dataCenters.find((dc) => dc.primary);
|
|
277
|
+
const spokes = dataCenters.filter((dc) => !dc.primary);
|
|
278
|
+
|
|
279
|
+
if (!hub || spokes.length === 0) {
|
|
280
|
+
throw new Error('Fan-Out requires 1 hub (primary) and 1+ spokes');
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return spokes.map((spoke) => ({
|
|
284
|
+
source: hub,
|
|
285
|
+
target: spoke,
|
|
286
|
+
topics,
|
|
287
|
+
replicationFactor: 3,
|
|
288
|
+
exactlyOnce: true,
|
|
289
|
+
syncConsumerOffsets: true,
|
|
290
|
+
}));
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Create Aggregation replication flows
|
|
295
|
+
*
|
|
296
|
+
* Region1 → Central, Region2 → Central, Region3 → Central
|
|
297
|
+
*/
|
|
298
|
+
private static createAggregationFlows(
|
|
299
|
+
dataCenters: DataCenterConfig[],
|
|
300
|
+
topics: string[]
|
|
301
|
+
): ReplicationFlowConfig[] {
|
|
302
|
+
const central = dataCenters.find((dc) => dc.primary);
|
|
303
|
+
const regions = dataCenters.filter((dc) => !dc.primary);
|
|
304
|
+
|
|
305
|
+
if (!central || regions.length === 0) {
|
|
306
|
+
throw new Error('Aggregation requires 1 central DC and 1+ regional DCs');
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return regions.map((region) => ({
|
|
310
|
+
source: region,
|
|
311
|
+
target: central,
|
|
312
|
+
topics,
|
|
313
|
+
renamePattern: {
|
|
314
|
+
from: '(.*)',
|
|
315
|
+
to: `${region.region}.$1`,
|
|
316
|
+
},
|
|
317
|
+
replicationFactor: 3,
|
|
318
|
+
exactlyOnce: true,
|
|
319
|
+
syncConsumerOffsets: false,
|
|
320
|
+
}));
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Generate MirrorMaker 2 connector configuration (JSON)
|
|
325
|
+
*/
|
|
326
|
+
static generateMM2ConnectorConfig(flow: ReplicationFlowConfig): string {
|
|
327
|
+
const connectorConfig = {
|
|
328
|
+
name: `mm2-${flow.source.id}-to-${flow.target.id}`,
|
|
329
|
+
'connector.class': 'org.apache.kafka.connect.mirror.MirrorSourceConnector',
|
|
330
|
+
'tasks.max': '1',
|
|
331
|
+
|
|
332
|
+
// Source cluster
|
|
333
|
+
'source.cluster.alias': flow.source.id,
|
|
334
|
+
'source.cluster.bootstrap.servers': flow.source.bootstrapServers.join(','),
|
|
335
|
+
|
|
336
|
+
// Target cluster
|
|
337
|
+
'target.cluster.alias': flow.target.id,
|
|
338
|
+
'target.cluster.bootstrap.servers': flow.target.bootstrapServers.join(','),
|
|
339
|
+
|
|
340
|
+
// Topics
|
|
341
|
+
'topics': flow.topics.join(','),
|
|
342
|
+
|
|
343
|
+
// Replication
|
|
344
|
+
'replication.factor': flow.replicationFactor || 3,
|
|
345
|
+
'refresh.topics.enabled': 'true',
|
|
346
|
+
'refresh.topics.interval.seconds': '600',
|
|
347
|
+
|
|
348
|
+
// Exactly-once
|
|
349
|
+
'exactly.once.support': flow.exactlyOnce ? 'enabled' : 'disabled',
|
|
350
|
+
|
|
351
|
+
// Offset sync
|
|
352
|
+
'sync.topic.acls.enabled': 'false',
|
|
353
|
+
'sync.topic.configs.enabled': 'true',
|
|
354
|
+
'offset-syncs.topic.replication.factor': flow.replicationFactor || 3,
|
|
355
|
+
|
|
356
|
+
// Checkpoints (consumer group offset sync)
|
|
357
|
+
'checkpoints.topic.replication.factor': flow.replicationFactor || 3,
|
|
358
|
+
'emit.checkpoints.enabled': flow.syncConsumerOffsets || false,
|
|
359
|
+
'emit.checkpoints.interval.seconds': '60',
|
|
360
|
+
|
|
361
|
+
// Heartbeats
|
|
362
|
+
'emit.heartbeats.enabled': 'true',
|
|
363
|
+
'emit.heartbeats.interval.seconds': '3',
|
|
364
|
+
'heartbeats.topic.replication.factor': flow.replicationFactor || 3,
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
// Add topic rename if specified
|
|
368
|
+
if (flow.renamePattern) {
|
|
369
|
+
connectorConfig['replication.policy.class'] = 'org.apache.kafka.connect.mirror.IdentityReplicationPolicy';
|
|
370
|
+
connectorConfig['topic.creation.default.replication.factor'] = flow.replicationFactor || 3;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
return JSON.stringify(connectorConfig, null, 2);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Generate Cluster Linking configuration (Confluent)
|
|
378
|
+
*/
|
|
379
|
+
static generateClusterLinkingConfig(link: ClusterLinkingConfig): string {
|
|
380
|
+
const config = {
|
|
381
|
+
'link.mode': link.mode,
|
|
382
|
+
'connection.mode': 'OUTBOUND',
|
|
383
|
+
'topic.creation.default.replication.factor': '3',
|
|
384
|
+
'topic.creation.default.partitions': '6',
|
|
385
|
+
'auto.create.mirror.topics.enable': link.autoCreateMirrorTopics !== false,
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
if (link.mirrorTopicPrefix) {
|
|
389
|
+
config['mirror.topic.prefix'] = link.mirrorTopicPrefix;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
const commands = [
|
|
393
|
+
`# Create cluster link`,
|
|
394
|
+
`confluent kafka link create ${link.linkName} \\`,
|
|
395
|
+
` --cluster ${link.destination.id} \\`,
|
|
396
|
+
` --source-cluster ${link.source.id} \\`,
|
|
397
|
+
` --source-bootstrap-server ${link.source.bootstrapServers.join(',')} \\`,
|
|
398
|
+
` --config-file link-config.properties`,
|
|
399
|
+
'',
|
|
400
|
+
`# Create mirror topics`,
|
|
401
|
+
...link.mirrorTopics.map(
|
|
402
|
+
(topic) => `confluent kafka mirror create ${topic} --link ${link.linkName}`
|
|
403
|
+
),
|
|
404
|
+
];
|
|
405
|
+
|
|
406
|
+
return commands.join('\n');
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Failover Orchestrator
|
|
412
|
+
*
|
|
413
|
+
* Manages failover and failback operations
|
|
414
|
+
*/
|
|
415
|
+
export class FailoverOrchestrator {
|
|
416
|
+
/**
|
|
417
|
+
* Initiate failover from primary to standby
|
|
418
|
+
*/
|
|
419
|
+
static async initiateFailover(
|
|
420
|
+
primary: DataCenterConfig,
|
|
421
|
+
standby: DataCenterConfig,
|
|
422
|
+
consumerGroups: string[]
|
|
423
|
+
): Promise<void> {
|
|
424
|
+
console.log(`🚨 Initiating failover: ${primary.id} → ${standby.id}`);
|
|
425
|
+
|
|
426
|
+
// Step 1: Stop producers in primary DC
|
|
427
|
+
console.log('1. Stopping producers in primary DC...');
|
|
428
|
+
|
|
429
|
+
// Step 2: Wait for replication lag to reach 0
|
|
430
|
+
console.log('2. Waiting for replication lag to reach 0...');
|
|
431
|
+
// TODO: Monitor consumer lag via Kafka metrics
|
|
432
|
+
|
|
433
|
+
// Step 3: Translate consumer offsets
|
|
434
|
+
console.log('3. Translating consumer group offsets...');
|
|
435
|
+
for (const group of consumerGroups) {
|
|
436
|
+
// MirrorMaker 2 checkpoints topic contains offset mappings
|
|
437
|
+
console.log(` - Translating offsets for group: ${group}`);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// Step 4: Switch DNS/load balancer to standby
|
|
441
|
+
console.log('4. Switching traffic to standby DC...');
|
|
442
|
+
|
|
443
|
+
// Step 5: Resume consumers in standby DC
|
|
444
|
+
console.log('5. Resuming consumers in standby DC...');
|
|
445
|
+
|
|
446
|
+
console.log('✅ Failover complete!');
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Initiate failback from standby to primary
|
|
451
|
+
*/
|
|
452
|
+
static async initiateFailback(
|
|
453
|
+
standby: DataCenterConfig,
|
|
454
|
+
primary: DataCenterConfig
|
|
455
|
+
): Promise<void> {
|
|
456
|
+
console.log(`🔄 Initiating failback: ${standby.id} → ${primary.id}`);
|
|
457
|
+
|
|
458
|
+
// Step 1: Setup reverse replication (standby → primary)
|
|
459
|
+
console.log('1. Setting up reverse replication...');
|
|
460
|
+
|
|
461
|
+
// Step 2: Wait for primary to catch up
|
|
462
|
+
console.log('2. Waiting for primary DC to catch up...');
|
|
463
|
+
|
|
464
|
+
// Step 3: Planned switchover during maintenance window
|
|
465
|
+
console.log('3. Executing planned switchover...');
|
|
466
|
+
|
|
467
|
+
// Step 4: Switch traffic back to primary
|
|
468
|
+
console.log('4. Switching traffic back to primary DC...');
|
|
469
|
+
|
|
470
|
+
console.log('✅ Failback complete!');
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* Example Usage: Active-Passive Replication
|
|
476
|
+
*
|
|
477
|
+
* ```typescript
|
|
478
|
+
* const dataCenters: DataCenterConfig[] = [
|
|
479
|
+
* {
|
|
480
|
+
* id: 'us-east',
|
|
481
|
+
* name: 'US East (Primary)',
|
|
482
|
+
* region: 'us-east-1',
|
|
483
|
+
* bootstrapServers: ['kafka1.us-east.example.com:9092'],
|
|
484
|
+
* primary: true,
|
|
485
|
+
* },
|
|
486
|
+
* {
|
|
487
|
+
* id: 'us-west',
|
|
488
|
+
* name: 'US West (DR)',
|
|
489
|
+
* region: 'us-west-2',
|
|
490
|
+
* bootstrapServers: ['kafka1.us-west.example.com:9092'],
|
|
491
|
+
* primary: false,
|
|
492
|
+
* },
|
|
493
|
+
* ];
|
|
494
|
+
*
|
|
495
|
+
* const config = MultiDCReplicationManager.generateMirrorMaker2Config(
|
|
496
|
+
* ReplicationTopology.ACTIVE_PASSIVE,
|
|
497
|
+
* dataCenters,
|
|
498
|
+
* ['orders', 'users', 'analytics.*']
|
|
499
|
+
* );
|
|
500
|
+
*
|
|
501
|
+
* // Generate connector config
|
|
502
|
+
* const connectorConfig = MultiDCReplicationManager.generateMM2ConnectorConfig(
|
|
503
|
+
* config.flows[0]
|
|
504
|
+
* );
|
|
505
|
+
* console.log(connectorConfig);
|
|
506
|
+
* ```
|
|
507
|
+
*/
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Example Usage: Active-Active Replication
|
|
511
|
+
*
|
|
512
|
+
* ```typescript
|
|
513
|
+
* const dataCenters: DataCenterConfig[] = [
|
|
514
|
+
* {
|
|
515
|
+
* id: 'us',
|
|
516
|
+
* name: 'United States',
|
|
517
|
+
* region: 'us-east-1',
|
|
518
|
+
* bootstrapServers: ['kafka-us.example.com:9092'],
|
|
519
|
+
* },
|
|
520
|
+
* {
|
|
521
|
+
* id: 'eu',
|
|
522
|
+
* name: 'Europe',
|
|
523
|
+
* region: 'eu-west-1',
|
|
524
|
+
* bootstrapServers: ['kafka-eu.example.com:9092'],
|
|
525
|
+
* },
|
|
526
|
+
* ];
|
|
527
|
+
*
|
|
528
|
+
* const config = MultiDCReplicationManager.generateMirrorMaker2Config(
|
|
529
|
+
* ReplicationTopology.ACTIVE_ACTIVE,
|
|
530
|
+
* dataCenters,
|
|
531
|
+
* ['user-events', 'click-stream']
|
|
532
|
+
* );
|
|
533
|
+
*
|
|
534
|
+
* // Topics at US: user-events, eu.user-events
|
|
535
|
+
* // Topics at EU: user-events, us.user-events
|
|
536
|
+
* ```
|
|
537
|
+
*/
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Example Usage: Cluster Linking (Confluent)
|
|
541
|
+
*
|
|
542
|
+
* ```typescript
|
|
543
|
+
* const link: ClusterLinkingConfig = {
|
|
544
|
+
* linkName: 'us-to-eu-link',
|
|
545
|
+
* source: {
|
|
546
|
+
* id: 'us-cluster',
|
|
547
|
+
* name: 'US Cluster',
|
|
548
|
+
* region: 'us-east-1',
|
|
549
|
+
* bootstrapServers: ['kafka-us.example.com:9092'],
|
|
550
|
+
* },
|
|
551
|
+
* destination: {
|
|
552
|
+
* id: 'eu-cluster',
|
|
553
|
+
* name: 'EU Cluster',
|
|
554
|
+
* region: 'eu-west-1',
|
|
555
|
+
* bootstrapServers: ['kafka-eu.example.com:9092'],
|
|
556
|
+
* },
|
|
557
|
+
* mode: 'DESTINATION',
|
|
558
|
+
* mirrorTopics: ['orders', 'users'],
|
|
559
|
+
* autoCreateMirrorTopics: true,
|
|
560
|
+
* };
|
|
561
|
+
*
|
|
562
|
+
* const commands = MultiDCReplicationManager.generateClusterLinkingConfig(link);
|
|
563
|
+
* console.log(commands);
|
|
564
|
+
* ```
|
|
565
|
+
*/
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Multi-DC Replication Best Practices:
|
|
569
|
+
*
|
|
570
|
+
* **MirrorMaker 2 vs Cluster Linking**:
|
|
571
|
+
* - MirrorMaker 2: Open source, works with all Kafka distributions
|
|
572
|
+
* - Cluster Linking: Confluent-only, lower latency, zero data duplication
|
|
573
|
+
*
|
|
574
|
+
* **Active-Passive**:
|
|
575
|
+
* - Use for disaster recovery (DR)
|
|
576
|
+
* - Enable consumer offset sync for failover
|
|
577
|
+
* - Test failover regularly (quarterly)
|
|
578
|
+
* - Monitor replication lag (target: < 1 second)
|
|
579
|
+
*
|
|
580
|
+
* **Active-Active**:
|
|
581
|
+
* - Use for multi-region writes
|
|
582
|
+
* - Prefix topics with source DC (us.orders, eu.orders)
|
|
583
|
+
* - Avoid bidirectional replication of same topics (infinite loop!)
|
|
584
|
+
* - Application must handle conflicts
|
|
585
|
+
*
|
|
586
|
+
* **Hub-Spoke**:
|
|
587
|
+
* - Use for aggregation (regional → central)
|
|
588
|
+
* - Prefix topics with spoke ID
|
|
589
|
+
* - Central hub for analytics/reporting
|
|
590
|
+
*
|
|
591
|
+
* **Latency Considerations**:
|
|
592
|
+
* - Same region: < 5ms
|
|
593
|
+
* - Cross-region (same continent): 30-50ms
|
|
594
|
+
* - Intercontinental: 100-300ms
|
|
595
|
+
* - Use compression to reduce network overhead
|
|
596
|
+
*
|
|
597
|
+
* **Failover RPO/RTO**:
|
|
598
|
+
* - RPO (Recovery Point Objective): < 1 minute (with offset sync)
|
|
599
|
+
* - RTO (Recovery Time Objective): 5-15 minutes (manual) or < 1 minute (automated)
|
|
600
|
+
*/
|
|
601
|
+
|
|
602
|
+
export default {
|
|
603
|
+
MultiDCReplicationManager,
|
|
604
|
+
FailoverOrchestrator,
|
|
605
|
+
ReplicationTopology,
|
|
606
|
+
ReplicationStrategy,
|
|
607
|
+
};
|