PostgreSQL to OpenSearch data synchronization using CDC (Change Data Capture) with Debezium, Kafka, and a consumer application.
PostgreSQL → Debezium (CDC) → Kafka → Consumer App (Go) → OpenSearch
- Change Data Capture: Debezium captures database changes from PostgreSQL
- Event Streaming: Kafka handles event distribution and replay capability
- Consumer Application: Golang application processes events and syncs to OpenSearch
- Plugin System: Extensible architecture for custom data sources and transformations
- Docker and Docker Compose
- AI agent with SpecKit commands (Claude Code, etc.)
Initialize SpecKit commands for this repo:
export CODEX_CONFIG_DIR="$HOME/.codex"
export CODEX_HOME=$(pwd)/.codex
uvx --from git+https://github.com/github/spec-kit.git specify init --ai codex --hereThis project follows a structured specification-driven development workflow using SpecKit commands. The workflow ensures proper planning, design, and implementation with built-in quality gates.
Follow these steps in order to develop features:
/speckit.constitutionDefine or update the project's core principles, technology constraints, and governance rules. This step establishes the foundation for all development decisions.
Status: ✅ Completed (v1.0.1)
/speckit.specify "Feature description here"Create a detailed specification for your feature including:
- User stories with priorities (P1, P2, P3)
- Functional requirements
- Acceptance criteria
- Success metrics
Output: /specs/[###-feature-name]/spec.md
/speckit.planGenerate a comprehensive implementation plan with:
- Technical context and dependencies
- Constitution compliance check
- Project structure
- Research findings
- Data models and API contracts
Output: /specs/[###-feature-name]/plan.md, research.md, data-model.md, contracts/
/speckit.tasksConvert the implementation plan into dependency-ordered, executable tasks organized by user story for independent implementation and testing.
Output: /specs/[###-feature-name]/tasks.md
/speckit.implementExecute all tasks from tasks.md, implementing features according to the plan with proper testing and validation at each checkpoint.
These commands improve quality and reduce risk but are not required:
/speckit.clarifyWhen to use: After /speckit.specify, before /speckit.plan
Identifies underspecified areas in the feature specification by asking targeted clarification questions. Use this to de-risk ambiguous requirements before investing in detailed planning.
/speckit.analyzeWhen to use: After /speckit.tasks, before /speckit.implement
Performs cross-artifact consistency analysis across spec.md, plan.md, and tasks.md to catch misalignments, gaps, or inconsistencies.
/speckit.checklistWhen to use: After /speckit.plan
Generates custom quality checklists to validate requirements completeness, clarity, and consistency based on the feature domain.
The project follows these core principles (see .specify/memory/constitution.md for full details):
- Plugin Architecture: Standalone, pluggable components for extensibility
- Event-Driven Integration: CDC events flow through Kafka with clear contracts
- Integration Testing (NON-NEGOTIABLE): TDD for integration tests, full pipeline coverage required
- Observability & Debugging: Structured JSON logging, correlation IDs, health checks
- Docker-First Deployment: All services via Docker Compose,
docker-compose upfor full pipeline
- Data Capture: Debezium PostgreSQL connector
- Message Queue: Apache Kafka with consumer groups
- Search Engine: OpenSearch
- Consumer Application: Golang (preferred)
- Container Orchestration: Docker Compose (local/test), Kubernetes-compatible for production
Here's a complete example of developing a new feature:
# 1. Create specification for syncing user table
/speckit.specify "Sync user table from PostgreSQL to OpenSearch with real-time updates"
# 2. (Optional) Clarify any ambiguous requirements
/speckit.clarify
# 3. Generate implementation plan
/speckit.plan
# 4. (Optional) Generate validation checklist
/speckit.checklist
# 5. Generate actionable tasks
/speckit.tasks
# 6. (Optional) Validate consistency before implementation
/speckit.analyze
# 7. Execute implementation
/speckit.implementdata-sync-opensearch/
├── .specify/
│ ├── memory/
│ │ └── constitution.md # Project governance and principles
│ ├── templates/ # Templates for specs, plans, tasks
│ └── scripts/ # Automation scripts
├── specs/
│ └── [###-feature-name]/ # Feature-specific documentation
│ ├── spec.md # Feature specification
│ ├── plan.md # Implementation plan
│ ├── tasks.md # Actionable task list
│ ├── research.md # Research findings
│ ├── data-model.md # Data models
│ └── contracts/ # API contracts
├── postgres/ # PostgreSQL datasource
│ ├── tests/ # PostgreSQL integration tests
│ └── ...
├── debezium/ # Debezium CDC configuration
│ ├── tests/ # Debezium integration tests
│ └── ...
├── src/ # Source code (to be created)
└── docker-compose.yml # Service orchestration
Quickstart guide: specs/004-opensearch-setup/quickstart.md
make start-opensearch
make create-indices
make load-demo-data
make run-demo-queriesThe local ops console provides a browser entry point for pipeline observation and benchmark control.
make start-ops-console
open http://localhost:8090It links to Kafbat UI, Kafka UI, and OpenSearch Dashboards, probes producer/consumer/OpenSearch health, scales consumer replicas, and launches benchmark runs with adjustable scenario, RPS, and duration. The console uses Docker Compose from inside the container, so set DOCKER_SOCKET in .env if your Docker socket is not /var/run/docker.sock (for example Colima).
Feature branches follow the pattern: ###-feature-name
All feature work is tracked in /specs/[###-feature-name]/ directory.
- Integration tests MUST pass before PR approval
- Kafka message schema validation required
- OpenSearch document structure verified
- End-to-end pipeline test (PostgreSQL write → OpenSearch read) required
- Plugin follows extension contract
- Structured logging with correlation IDs implemented
- Docker Compose service definition included
- Integration test coverage validated
- Constitution principles compliance verified
Get started with the PostgreSQL database and sample data:
# Start PostgreSQL with sample data
make start
# Verify setup
make health
# View schema and sample data
make inspect-schema
make inspect-dataWhat gets loaded:
- 500K YouTube comments from Hugging Face dataset
- Normalized into 3 tables: videos, users, comments
- CDC-ready with WAL enabled for Debezium
- Database is ephemeral; data resets on container restart
Available commands:
make start- Start PostgreSQL and load sample datamake load-data- Load CSVs into PostgreSQLmake stop- Stop PostgreSQLmake reset- Reset database to clean statemake health- Check database statusmake inspect-schema- View table structuresmake inspect-data- View sample records
See postgres/quickstart.md for detailed setup guide.
Configure Change Data Capture to stream PostgreSQL changes to Kafka:
# Start CDC services (Kafka, Kafka UI, Debezium Connect)
make start-cdc
# Check connector status
make status-cdc
# Restart connector
make restart-cdc
# Stop CDC services
make stop-cdcWhat gets configured:
- Kafka broker with KRaft mode (Confluent Platform 7.6.0)
- Debezium Connect 2.5 with PostgreSQL connector
- Kafka UI for monitoring and topic visualization
- CDC topics:
dbserver.public.videos,dbserver.public.users,dbserver.public.comments - Automatic connector registration on startup
Web Interfaces:
- Kafka UI: http://localhost:8081 - Monitor topics, consumers, and CDC events
- Kafbat UI: http://localhost:8084 - Kafka metadata, consumer groups, lag, and Kafka Connect visibility
- Kafka Connect API: http://localhost:8083 - REST API for connector management
Integration Tests:
# Test connector registration
bash debezium/tests/test-connector-registration.sh
# Test CDC event capture
bash debezium/tests/test-cdc-capture.sh
# Test offset recovery
bash debezium/tests/test-offset-recovery.shKey Features:
- Real-time CDC: Changes captured within seconds
- Initial snapshot: 895K records (videos + users + comments)
- ARM64 compatible: Works on Apple Silicon
- Offset management: No data loss on restart
- Event format: Debezium envelope with full CDC metadata (before/after, op, source)
Available commands:
make start-cdc- Start Kafka, Connect, UI, and register connectormake stop-cdc- Stop CDC servicesmake restart-cdc- Restart connector (delete + re-register)make status-cdc- Check connector healthmake register-connector- Manually register connector
See debezium/README.md for detailed CDC documentation and specs/002-cdc-setup/quickstart.md for setup guide.
All service configuration via environment variables. Secrets managed through Docker secrets or external secret management (never committed to repository).
- Review the constitution (
.specify/memory/constitution.md) - Follow the SpecKit workflow for all features
- Ensure integration tests pass
- Verify Docker Compose compatibility
- Include correlation IDs in all logs
[Specify your license here]
For issues or questions about the SpecKit workflow, refer to the command documentation in .claude/commands/ or .specify/templates/.