Thanks for contributing. This guide explains how to work in this repository safely and consistently.
- Development Environment Setup
- Project Structure
- Architecture Rules
- Coding Standards
- Branch Naming
- Commit Messages
- Testing
- Pull Request Process
- Code Review Checklist
| Tool | Version |
|---|---|
| Java (JDK) | 25 |
| Maven | 3.9+ |
| Docker Desktop | Latest stable |
| Node.js | 20 |
| npm | 10+ |
| Git | 2.40+ |
-
Clone the repository:
git clone https://github.com/<owner>/autocomplete-system.git Set-Location .\autocomplete-system
-
Copy the env template and set required values:
Copy-Item .env.example .env -
Start the stack:
docker compose up -d --build
-
Verify services:
docker compose ps
-
(Optional for local non-Docker app runs) install shared module first:
Set-Location .\common mvn -B -DskipTests install
common/- shared runtime contracts (KafkaTopics,RedisKeys, DTO/util classes)search-service/- write side: search intake + Kafka Streams aggregation + PostgreSQL writescdc-service/- Debezium CDC consumer + Redis prefix index updaterautocomplete-service/- query side: suggestions from Redisfrontend/- Angular UI + API proxy/nginxinfra/- bootstrap assets for Kafka, Debezium, PostgreSQL, Redisdocker-compose.yml- full local environment
When changing behavior, trace the full flow:
frontend -> /api/search -> search-service -> search-events -> SearchStatsTopology -> search_stats -> Debezium -> cdc-service -> Redis -> autocomplete-service -> /api/complete
Required rules:
- Keep controllers thin; place logic in services/producers/topologies.
- Do not bypass CDC by writing autocomplete data from
search-servicedirectly to Redis. - Keep query normalization (
trim + lowercase) consistent in write/index/query path. - Parse Debezium envelope via
payload.after; do not assume flat CDC JSON. - Use identifiers from
common(KafkaTopics,RedisKeys) instead of hardcoding names. - Keep migration files mirrored between:
search-service/src/main/resources/db/migration/infra/postgres/
- Keep
frontend/proxy.conf.jsonandfrontend/nginx.confaligned for API route changes.
- Prefer readable, small methods and explicit naming.
- Keep module boundaries clean (no cross-service shortcuts).
- Preserve strict profile compatibility (
SPRING_PROFILES_ACTIVE=strict).
- Java 25 features are allowed when they improve clarity.
- Reuse constants from
commonfor topics/prefixes. - Follow existing package layout
lt.satsyuk.<module>. - Add or update tests for behavioral changes.
- Keep business logic out of UI service layers unless UI-specific.
autocomplete.service.tsshould stay focused on debouncing + HTTP + UI composition.- Keep API paths consistent with proxy/nginx configs.
- Never commit real secrets or credentials.
- Keep secrets in
.envonly. - Redact sensitive values when sharing logs.
Use one of the prefixes:
| Prefix | Purpose | Example |
|---|---|---|
feat/ |
New feature | feat/add-prefix-boosting |
fix/ |
Bug fix | fix/fix-cdc-envelope-parse |
hotfix/ |
Urgent production fix | hotfix/fix-redis-clear-timeout |
chore/ |
Maintenance | chore/update-workflow-actions |
docs/ |
Documentation changes | docs/update-readme-ci-section |
test/ |
Test-only changes | test/add-cdc-truncate-it |
Use Conventional Commits:
<type>(<scope>): <short description>
Common types: feat, fix, docs, refactor, test, chore, ci, perf
Examples:
feat(search-service): add state store override for streams topology
fix(cdc-service): block updates during truncate clear window
docs: align readme with current ci workflow
ci: add telegram notification summary step
Backend modules are independent Maven projects.
Set-Location .\search-service
mvn -B -ntp test
Set-Location ..\cdc-service
mvn -B -ntp test
Set-Location ..\autocomplete-service
mvn -B -ntp testSet-Location .\search-service
mvn -B -ntp test-compile failsafe:integration-test failsafe:verify
Set-Location ..\cdc-service
mvn -B -ntp test-compile failsafe:integration-test failsafe:verify
Set-Location ..\autocomplete-service
mvn -B -ntp test-compile failsafe:integration-test failsafe:verifySet-Location .\frontend
npm ci
npm run lint --if-present
npm run test:ci
npm run build --if-presentVerifies the full pipeline end-to-end: seeds search events, waits for Redis prefix index to populate, opens the UI in a headless browser, and asserts seeded suggestions order by score with correct click-through behavior.
Requires Docker Desktop running and .env populated (Copy-Item .env.example .env).
# Stack must already be up
Set-Location .\frontend
npm run test:e2e-smokeTo start the stack, run, and tear down:
docker compose up -d --build
Set-Location .\frontend
npm run test:e2e-smoke
Set-Location ..
docker compose down -vdocker compose logs --tail=100 search-service
docker compose logs --tail=100 cdc-service
docker compose exec redis redis-cli ZREVRANGE autocomplete:ja 0 9 WITHSCORESFor a fully automated end-to-end check, use the smoke test:
Set-Location .\frontend
npm run test:e2e-smoke- Create a branch from
main. - Implement changes with tests.
- Run relevant backend/frontend checks locally.
- Run E2E smoke test if pipeline behavior was affected:
npm run test:e2e-smokefromfrontend/. - Verify docs/configs are in sync when needed:
- migrations +
infra/postgres proxy.conf.json+nginx.conf
- migrations +
- Open a PR to
mainwith:- change summary
- affected pipeline stage(s)
- test evidence
- Address review comments.
- Merge after CI passes (including
frontend-e2e-smokejob).
- Change follows pipeline architecture and service boundaries
- No hardcoded Kafka topic or Redis key names outside
common - Lowercase normalization preserved on write/index/query path
- Debezium parsing uses envelope (
payload.after) - Schema changes mirrored in both migration locations
- Relevant unit/integration/frontend tests are updated
- E2E smoke passes locally (
npm run test:e2e-smoke) if pipeline behavior changed -
frontend/proxy.conf.jsonandfrontend/nginx.confare aligned (if routes changed) - No secrets committed; logs/examples are redacted
- Commit messages follow Conventional Commits