exness-data-preprocess 1.1.0__tar.gz → 1.2.1__tar.gz
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.
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/.gitignore +5 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/.mise.toml +41 -3
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/CHANGELOG.md +19 -0
- exness_data_preprocess-1.2.1/CLAUDE.md +150 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/CONTRIBUTING.md +14 -20
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/PKG-INFO +1 -1
- exness_data_preprocess-1.2.1/docs/adr/2025-12-10-clickhouse-pydantic-config.md +237 -0
- exness_data_preprocess-1.2.1/docs/adr/diagrams/2025-12-10-clickhouse-pydantic-config-after.dot +21 -0
- exness_data_preprocess-1.2.1/docs/adr/diagrams/2025-12-10-clickhouse-pydantic-config-arch.dot +17 -0
- exness_data_preprocess-1.2.1/docs/adr/diagrams/2025-12-10-clickhouse-pydantic-config-before.dot +20 -0
- exness_data_preprocess-1.2.1/docs/design/2025-12-10-clickhouse-pydantic-config/spec.md +153 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/pyproject.toml +1 -1
- exness_data_preprocess-1.2.1/scripts/generate_dbeaver_config.py +212 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/src/exness_data_preprocess/__init__.py +1 -1
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/src/exness_data_preprocess/clickhouse_client.py +26 -10
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/src/exness_data_preprocess/clickhouse_manager.py +80 -105
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/src/exness_data_preprocess/clickhouse_query_engine.py +53 -59
- exness_data_preprocess-1.1.0/.lint-relative-paths-results.txt +0 -62
- exness_data_preprocess-1.1.0/CLAUDE.md +0 -213
- exness_data_preprocess-1.1.0/docs/archive/CLAUDE_MD_AUDIT_2025-10-16_PASS2.md +0 -378
- exness_data_preprocess-1.1.0/docs/archive/CLAUDE_MD_VERIFICATION_CHECKLIST_2025-10-16.md +0 -438
- exness_data_preprocess-1.1.0/docs/archive/CLAUDE_MD_VERIFICATION_FINDINGS_2025-10-16.md +0 -340
- exness_data_preprocess-1.1.0/docs/archive/DOCUMENTATION_AUDIT_2025-10-15.md +0 -363
- exness_data_preprocess-1.1.0/docs/archive/DOCUMENTATION_AUDIT_PASS2_2025-10-15.md +0 -208
- exness_data_preprocess-1.1.0/docs/archive/DOCUMENTATION_BEST_PRACTICES_LINE_COUNTS.md +0 -527
- exness_data_preprocess-1.1.0/docs/archive/E2E_TESTING_PLAN_v1.0.0.md +0 -197
- exness_data_preprocess-1.1.0/docs/archive/EXCHANGE_SESSION_AUDIT_2025-10-17.md +0 -520
- exness_data_preprocess-1.1.0/docs/archive/FUNCTIONALITY_VALIDATION_REPORT_2025-10-15.md +0 -415
- exness_data_preprocess-1.1.0/docs/archive/FUNCTIONALITY_VALIDATION_REPORT_2025-10-16.md +0 -386
- exness_data_preprocess-1.1.0/docs/archive/GAP_DETECTION_COMPARISON.md +0 -496
- exness_data_preprocess-1.1.0/docs/archive/GAP_DETECTION_SQL_APPROACH.md +0 -434
- exness_data_preprocess-1.1.0/docs/archive/REFACTORING_CHECKLIST.md +0 -219
- exness_data_preprocess-1.1.0/docs/archive/RESEARCH_PATTERNS_CANONICALIZATION_2025-10-17.md +0 -315
- exness_data_preprocess-1.1.0/docs/archive/SCHEMA_v1.6.0_AUDIT_FINDINGS.md +0 -434
- exness_data_preprocess-1.1.0/docs/archive/SCHEMA_v1.6.0_MIGRATION_GUIDE.md +0 -574
- exness_data_preprocess-1.1.0/docs/archive/SESSION_2025-10-15_SUMMARY.md +0 -342
- exness_data_preprocess-1.1.0/docs/archive/UNIFIED_DUCKDB_PLAN_v1.0.0_LEGACY.md +0 -705
- exness_data_preprocess-1.1.0/docs/archive/implementation-plan-2024-11-24.yaml +0 -36
- exness_data_preprocess-1.1.0/docs/validation/ARCHITECTURE_AUDIT_2025-10-17.md +0 -406
- exness_data_preprocess-1.1.0/docs/validation/ARCHITECTURE_EFFICIENCY_AUDIT_2025-10-18.md +0 -374
- exness_data_preprocess-1.1.0/docs/validation/DOCUMENTATION_SURVEY_v1.7.0.md +0 -294
- exness_data_preprocess-1.1.0/docs/validation/WEEKEND_GAP_VALIDATION_SUMMARY.md +0 -109
- exness_data_preprocess-1.1.0/docs/validation/WORKSPACE_SURVEY_2025-10-17.md +0 -267
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/.cz.toml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/.github/workflows/ci.yml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/.github/workflows/pre-commit-autoupdate.yml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/.github/workflows/publish.yml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/.pre-commit-config.yaml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/.releaserc.yml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/LICENSE +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/Makefile +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/README.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/cliff-release-notes.toml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/cliff.toml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/DATABASE_SCHEMA.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/EXNESS_DATA_SOURCES.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/MODULE_ARCHITECTURE.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/PRIORITY3_CLEANUP_PLAN.yaml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/README.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/REPOSITORY_REFACTORING_PLAN.yaml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/RESEARCH_PATTERNS.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/TRADING_HOURS_RESEARCH.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/UNIFIED_DUCKDB_PLAN_v2.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/adr/2025-12-09-codebase-pruning.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/adr/2025-12-09-exness-clickhouse-migration.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/adr/2025-12-10-clickhouse-e2e-validation-pipeline.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/archive/PHASE4_DRY_RUN_CONFIG_PLAN.yaml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/archive/PHASE7_v1.5.0_REFACTORING_PLAN.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/archive/PHASE7_v1.6.0_REFACTORING_PROGRESS.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/archive/PYDANTIC_REFACTORING_PLAN_v0.2.0_COMPLETE.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/archive/PYDANTIC_REFACTORING_STATUS_v0.2.0_COMPLETE.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/design/2025-12-09-codebase-pruning/spec.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/design/2025-12-09-exness-clickhouse-migration/spec.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/design/2025-12-10-clickhouse-e2e-validation-pipeline/spec.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/optimization/OPTIMIZATION_OPPORTUNITIES_2025-10-18.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/phases/PHASE2_SESSION_VECTORIZATION_PLAN.yaml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/phases/PHASE3_SQL_GAP_DETECTION_PLAN.yaml +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/releases/RELEASE_NOTES.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/releases/RELEASE_NOTES_SHORT.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/HYBRID_SESSION_DETECTION_ANALYSIS.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/compression-benchmarks/README.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/compression-benchmarks/test_all_compression_methods.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/compression-benchmarks/test_delta_encoding_properly.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/compression-benchmarks/test_parquet_compression_methods.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-spread-analysis/01-methodology.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-spread-analysis/02-mode-truncated-analysis.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-spread-analysis/03-hurdle-model-analysis.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-spread-analysis/04-temporal-patterns.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-spread-analysis/05-final-recommendations.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-spread-analysis/README.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-spread-analysis/scripts/reproduction_guide.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-spread-analysis/visualizations/hurdle-model/hurdle_decomposition.png +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/cv_mode_comparison.png +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/distribution_overlay.png +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/signal_quality_comparison.png +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-spread-analysis/visualizations/mode-truncated/variance_decomposition.png +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-spread-analysis/visualizations/temporal/concentration_curve.png +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-spread-analysis/visualizations/temporal/percentile_analysis.png +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/01-methodology.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/02-baseline-sep2024.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/03-multiperiod-validation.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/04-discoveries-and-plan-evolution.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/README.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/findings/baseline-sep2024-comprehensive-summary.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/findings/phase2-mean-reversion-report.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/findings/phase3-volatility-model-report.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/findings/phase4-5-statistical-tests-survivorship-report.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/scripts/baseline-sep2024/01_mean_reversion_analysis.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/scripts/baseline-sep2024/02_volatility_model_simple.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/scripts/baseline-sep2024/03_liquidity_crisis_detection.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/scripts/baseline-sep2024/04_regime_detection_analysis.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase1_data_validation.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase2_mean_reversion.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase3_volatility_model.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase4_statistical_tests.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase5_survivorship_bias.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase5_survivorship_bias_v1.0.1.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase6a_interval_analysis.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase6b_price_clustering.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/scripts/multiperiod-validation/phase6c_combined_pattern.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/scripts/reproduction_guide.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/scripts/visualization/diagnostic_burst_decay.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/scripts/visualization/generate_interactive_dashboard.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/scripts/visualization/generate_lightweight_dashboard.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/eurusd-zero-spread-deviations/scripts/visualization/prepare_visualization_data.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/research/gap_detection_implementation_example.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/setup/GITHUB_PYPI_SETUP.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/validation/E2E_VALIDATION_RESULTS_v1.6.0.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/validation/SPIKE_TEST_RESULTS_PHASE1_2025-10-18.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/docs/validation/SPIKE_TEST_RESULTS_PHASE2_2025-10-18.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/examples/basic_usage.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/examples/batch_processing.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/package-lock.json +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/package.json +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/src/exness_data_preprocess/clickhouse_base.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/src/exness_data_preprocess/clickhouse_gap_detector.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/src/exness_data_preprocess/clickhouse_ohlc_generator.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/src/exness_data_preprocess/config.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/src/exness_data_preprocess/database_manager.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/src/exness_data_preprocess/downloader.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/src/exness_data_preprocess/exchanges.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/src/exness_data_preprocess/gap_detector.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/src/exness_data_preprocess/models.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/src/exness_data_preprocess/ohlc_generator.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/src/exness_data_preprocess/processor.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/src/exness_data_preprocess/query_engine.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/src/exness_data_preprocess/schema.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/src/exness_data_preprocess/session_detector.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/src/exness_data_preprocess/tick_loader.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/tests/README.md +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/tests/__init__.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/tests/conftest.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/tests/test_basic.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/tests/test_functional_regression.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/tests/test_models.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/tests/test_processor_pydantic.py +0 -0
- {exness_data_preprocess-1.1.0 → exness_data_preprocess-1.2.1}/tests/test_types.py +0 -0
|
@@ -2,15 +2,32 @@
|
|
|
2
2
|
# E2E validation workflow for codebase pruning verification
|
|
3
3
|
|
|
4
4
|
[env]
|
|
5
|
-
# Python version for validation
|
|
6
|
-
PYTHON_VERSION = "3.
|
|
5
|
+
# Python version for validation (pinned for alpha-forge compatibility)
|
|
6
|
+
PYTHON_VERSION = "3.11"
|
|
7
7
|
# Package name
|
|
8
8
|
PACKAGE_NAME = "exness_data_preprocess"
|
|
9
9
|
# Validation temp directory
|
|
10
10
|
VALIDATION_TMP = "./tmp/validation"
|
|
11
11
|
|
|
12
|
+
# ADR: /docs/adr/2025-12-10-clickhouse-pydantic-config.md
|
|
13
|
+
# ClickHouse SSoT Configuration
|
|
14
|
+
# Connection identity
|
|
15
|
+
CLICKHOUSE_NAME = "exness-clickhouse-local"
|
|
16
|
+
CLICKHOUSE_MODE = "local" # "local" or "cloud"
|
|
17
|
+
CLICKHOUSE_TYPE = "dev" # "dev", "test", or "prod"
|
|
18
|
+
# Connection parameters (match existing clickhouse_client.py defaults)
|
|
19
|
+
CLICKHOUSE_HOST = "localhost"
|
|
20
|
+
CLICKHOUSE_PORT = "8123"
|
|
21
|
+
CLICKHOUSE_DATABASE = "exness"
|
|
22
|
+
# Output paths
|
|
23
|
+
DBEAVER_CONFIG_PATH = ".dbeaver/data-sources.json"
|
|
24
|
+
# Cloud credentials (read from .env for security)
|
|
25
|
+
# CLICKHOUSE_USER_READONLY - set in .env
|
|
26
|
+
# CLICKHOUSE_PASSWORD_READONLY - set in .env
|
|
27
|
+
|
|
12
28
|
[tools]
|
|
13
|
-
|
|
29
|
+
# Pin Python 3.11 for alpha-forge compatibility (numpy requirements)
|
|
30
|
+
python = "3.11"
|
|
14
31
|
|
|
15
32
|
# =============================================================================
|
|
16
33
|
# Validation Tasks - E2E Testing Pipeline
|
|
@@ -470,3 +487,24 @@ engine.close()
|
|
|
470
487
|
print('✅ OHLC validation passed')
|
|
471
488
|
"
|
|
472
489
|
'''
|
|
490
|
+
|
|
491
|
+
# =============================================================================
|
|
492
|
+
# DBeaver Config Generation
|
|
493
|
+
# ADR: /docs/adr/2025-12-10-clickhouse-pydantic-config.md
|
|
494
|
+
# =============================================================================
|
|
495
|
+
|
|
496
|
+
[tasks.db-client-generate]
|
|
497
|
+
description = "Generate DBeaver config from Pydantic model"
|
|
498
|
+
run = "uv run scripts/generate_dbeaver_config.py --output ${DBEAVER_CONFIG_PATH}"
|
|
499
|
+
|
|
500
|
+
[tasks."db-client:cloud"]
|
|
501
|
+
description = "Generate config for ClickHouse Cloud"
|
|
502
|
+
run = "uv run scripts/generate_dbeaver_config.py --mode cloud --output ${DBEAVER_CONFIG_PATH}"
|
|
503
|
+
|
|
504
|
+
[tasks."db-client:dry-run"]
|
|
505
|
+
description = "Preview generated config without writing"
|
|
506
|
+
run = "uv run scripts/generate_dbeaver_config.py --dry-run"
|
|
507
|
+
|
|
508
|
+
[tasks.dbeaver]
|
|
509
|
+
description = "Launch DBeaver with project workspace"
|
|
510
|
+
run = '"/Applications/DBeaver.app/Contents/MacOS/dbeaver" -data .dbeaver-workspace &'
|
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
## [1.2.1](https://github.com/terrylica/exness-data-preprocess/compare/v1.2.0...v1.2.1) (2025-12-11)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **clickhouse:** bootstrap database creation without existing database context ([0fdfef1](https://github.com/terrylica/exness-data-preprocess/commit/0fdfef17cf797d64a66b3b163037a01c1e8245a7))
|
|
7
|
+
|
|
8
|
+
# [1.2.0](https://github.com/terrylica/exness-data-preprocess/compare/v1.1.0...v1.2.0) (2025-12-10)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **clickhouse:** resolve E2E validation bugs in schema and query engine ([5c618f7](https://github.com/terrylica/exness-data-preprocess/commit/5c618f717cadc23097e9fd11d2fed87947ecf25f))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
* add DBeaver config generation with CLICKHOUSE_MODE support ([0e97618](https://github.com/terrylica/exness-data-preprocess/commit/0e9761818f137461623f744af92f0b1e98b3a797))
|
|
19
|
+
|
|
1
20
|
# [1.1.0](https://github.com/terrylica/exness-data-preprocess/compare/v1.0.0...v1.1.0) (2025-12-10)
|
|
2
21
|
|
|
3
22
|
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
**Package**: `exness-data-preprocess` — Forex tick data preprocessing with DuckDB (local) and ClickHouse (cloud) backends
|
|
6
|
+
|
|
7
|
+
**Version**: See [`pyproject.toml`](pyproject.toml) line 3 (SSoT via semantic-release)
|
|
8
|
+
|
|
9
|
+
**Quick Start**: [`README.md`](README.md) — Installation, API reference, usage examples
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Documentation Hub (Progressive Disclosure)
|
|
14
|
+
|
|
15
|
+
### Essential Links
|
|
16
|
+
|
|
17
|
+
| Topic | SSoT Document | Purpose |
|
|
18
|
+
| ---------------- | ------------------------------------------------------------------ | ------------------------------------- |
|
|
19
|
+
| **User Guide** | [`README.md`](README.md) | Installation, API, examples |
|
|
20
|
+
| **Architecture** | [`docs/UNIFIED_DUCKDB_PLAN_v2.md`](docs/UNIFIED_DUCKDB_PLAN_v2.md) | Unified single-file DuckDB design |
|
|
21
|
+
| **Schema** | [`docs/DATABASE_SCHEMA.md`](docs/DATABASE_SCHEMA.md) | Phase7 30-column OHLC specification |
|
|
22
|
+
| **Modules** | [`docs/MODULE_ARCHITECTURE.md`](docs/MODULE_ARCHITECTURE.md) | 19 modules with SLOs |
|
|
23
|
+
| **Data Sources** | [`docs/EXNESS_DATA_SOURCES.md`](docs/EXNESS_DATA_SOURCES.md) | Exness tick data variants |
|
|
24
|
+
| **Research** | [`docs/RESEARCH_PATTERNS.md`](docs/RESEARCH_PATTERNS.md) | Hybrid materialization lifecycle |
|
|
25
|
+
| **Tasks** | [`.mise.toml`](.mise.toml) | Validation, ClickHouse, DBeaver tasks |
|
|
26
|
+
| **Contributing** | [`CONTRIBUTING.md`](CONTRIBUTING.md) | Development guidelines |
|
|
27
|
+
|
|
28
|
+
### Deep Dives (On-Demand)
|
|
29
|
+
|
|
30
|
+
| Topic | Location | When to Read |
|
|
31
|
+
| ------------------ | -------------------------------------- | -------------------------------- |
|
|
32
|
+
| ADRs | [`docs/adr/`](docs/adr/) | Architecture decisions |
|
|
33
|
+
| Design Specs | [`docs/design/`](docs/design/) | Implementation blueprints |
|
|
34
|
+
| Optimization Plans | [`docs/phases/`](docs/phases/) | Phase 2/3 SSoT YAML plans |
|
|
35
|
+
| Validation Results | [`docs/validation/`](docs/validation/) | Spike test proofs |
|
|
36
|
+
| Research Analysis | [`docs/research/`](docs/research/) | Zero-spread, compression studies |
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Architecture Overview
|
|
41
|
+
|
|
42
|
+
### Dual Backend Design
|
|
43
|
+
|
|
44
|
+
| Backend | Storage | Use Case | Entry Point |
|
|
45
|
+
| -------------- | ----------------------------------------- | ----------------- | --------------------- |
|
|
46
|
+
| **DuckDB** | One file per instrument (`eurusd.duckdb`) | Local development | `ExnessDataProcessor` |
|
|
47
|
+
| **ClickHouse** | Single table with instrument column | Cloud deployment | `ClickHouseManager` |
|
|
48
|
+
|
|
49
|
+
### Module Structure (19 Modules)
|
|
50
|
+
|
|
51
|
+
**DuckDB Backend (8 modules)**:
|
|
52
|
+
|
|
53
|
+
- `processor.py` — Thin orchestrator facade
|
|
54
|
+
- `downloader.py` — HTTP download operations
|
|
55
|
+
- `tick_loader.py` — CSV parsing
|
|
56
|
+
- `database_manager.py` — Database operations
|
|
57
|
+
- `session_detector.py` — Holiday/session detection (vectorized)
|
|
58
|
+
- `gap_detector.py` — Incremental update logic (SQL-based)
|
|
59
|
+
- `ohlc_generator.py` — Phase7 OHLC generation
|
|
60
|
+
- `query_engine.py` — Query operations
|
|
61
|
+
|
|
62
|
+
**ClickHouse Backend (7 modules)**:
|
|
63
|
+
|
|
64
|
+
- `clickhouse_manager.py` — Schema management, data loading
|
|
65
|
+
- `clickhouse_gap_detector.py` — Gap detection for ClickHouse
|
|
66
|
+
- `clickhouse_query_engine.py` — Query with pagination
|
|
67
|
+
- `clickhouse_ohlc_generator.py` — OHLC generation
|
|
68
|
+
- `clickhouse_client.py` — Connection factory with error handling
|
|
69
|
+
- `clickhouse_base.py` — Shared mixin for client lifecycle
|
|
70
|
+
- `clickhouse_cloud.py` — Cloud-specific configuration
|
|
71
|
+
|
|
72
|
+
**Shared (4 modules)**:
|
|
73
|
+
|
|
74
|
+
- `config.py` — Configuration management
|
|
75
|
+
- `models.py` — Pydantic models (UpdateResult, CoverageInfo, etc.)
|
|
76
|
+
- `schema.py` — SQL schema definitions
|
|
77
|
+
- `exchanges.py` — Exchange calendar integration
|
|
78
|
+
|
|
79
|
+
**Complete Details**: [`docs/MODULE_ARCHITECTURE.md`](docs/MODULE_ARCHITECTURE.md)
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Development Commands
|
|
84
|
+
|
|
85
|
+
### Quick Reference
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# Setup
|
|
89
|
+
uv sync --dev
|
|
90
|
+
|
|
91
|
+
# Testing (48 tests)
|
|
92
|
+
uv run pytest # All tests
|
|
93
|
+
mise run validate # Full E2E validation
|
|
94
|
+
|
|
95
|
+
# Linting
|
|
96
|
+
uv run ruff check --fix src/ tests/
|
|
97
|
+
|
|
98
|
+
# ClickHouse
|
|
99
|
+
mise run clickhouse:start # Start local server
|
|
100
|
+
mise run clickhouse:status # Check connection
|
|
101
|
+
mise run validate:clickhouse # E2E ClickHouse tests
|
|
102
|
+
|
|
103
|
+
# Build & Publish
|
|
104
|
+
uv build
|
|
105
|
+
mise run db-client-generate # Generate DBeaver config
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### mise Tasks
|
|
109
|
+
|
|
110
|
+
All validation and tooling tasks are defined in [`.mise.toml`](.mise.toml):
|
|
111
|
+
|
|
112
|
+
| Task | Description |
|
|
113
|
+
| ------------------------------ | ------------------------------------------------------------------------- |
|
|
114
|
+
| `mise run validate` | Full E2E pipeline (imports, lint, typecheck, test, build, install, mixin) |
|
|
115
|
+
| `mise run validate:clickhouse` | ClickHouse E2E tests (requires running server) |
|
|
116
|
+
| `mise run clickhouse:start` | Start mise-installed ClickHouse |
|
|
117
|
+
| `mise run db-client-generate` | Generate DBeaver config from Pydantic model |
|
|
118
|
+
| `mise run ci` | Simulate CI pipeline locally |
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Key Patterns
|
|
123
|
+
|
|
124
|
+
### Performance Optimizations (~16x total speedup)
|
|
125
|
+
|
|
126
|
+
| Phase | Optimization | Speedup | SSoT |
|
|
127
|
+
| ----- | --------------------- | ----------------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
128
|
+
| 1 | Incremental OHLC | 7.3x | [`docs/validation/SPIKE_TEST_RESULTS_PHASE1_2025-10-18.md`](docs/validation/SPIKE_TEST_RESULTS_PHASE1_2025-10-18.md) |
|
|
129
|
+
| 2 | Session Vectorization | 2.2x | [`docs/phases/PHASE2_SESSION_VECTORIZATION_PLAN.yaml`](docs/phases/PHASE2_SESSION_VECTORIZATION_PLAN.yaml) |
|
|
130
|
+
| 3 | SQL Gap Detection | 46% LOC reduction | [`docs/phases/PHASE3_SQL_GAP_DETECTION_PLAN.yaml`](docs/phases/PHASE3_SQL_GAP_DETECTION_PLAN.yaml) |
|
|
131
|
+
|
|
132
|
+
### Research Lifecycle
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
Explore (pandas/Polars) → Validate → Graduate (DuckDB) → Query (SQL)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**SSoT**: [`docs/RESEARCH_PATTERNS.md`](docs/RESEARCH_PATTERNS.md)
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## References
|
|
143
|
+
|
|
144
|
+
- **Exness Data**: <https://ticks.ex2archive.com/>
|
|
145
|
+
- **DuckDB**: <https://duckdb.org/>
|
|
146
|
+
- **ClickHouse**: <https://clickhouse.com/>
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
**Last Updated**: 2025-12-10
|
|
@@ -6,7 +6,7 @@ Thank you for your interest in contributing to Exness Data Preprocess! This docu
|
|
|
6
6
|
|
|
7
7
|
### Prerequisites
|
|
8
8
|
|
|
9
|
-
- Python 3.
|
|
9
|
+
- Python 3.11 or higher (see `pyproject.toml` requires-python)
|
|
10
10
|
- uv package manager (recommended) or pip
|
|
11
11
|
- Git
|
|
12
12
|
|
|
@@ -114,6 +114,7 @@ When reporting issues, please include:
|
|
|
114
114
|
```
|
|
115
115
|
|
|
116
116
|
7. **Push to your fork** and submit a pull request:
|
|
117
|
+
|
|
117
118
|
```bash
|
|
118
119
|
git push origin feature/your-feature-name
|
|
119
120
|
```
|
|
@@ -143,31 +144,24 @@ test: add integration tests for DuckDB operations
|
|
|
143
144
|
|
|
144
145
|
### Project Structure
|
|
145
146
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
│ ├── test_processor.py # Processor tests
|
|
156
|
-
│ ├── test_api.py # API tests
|
|
157
|
-
│ └── test_cli.py # CLI tests
|
|
158
|
-
├── docs/ # Documentation
|
|
159
|
-
├── pyproject.toml # Package configuration
|
|
160
|
-
└── README.md # Main documentation
|
|
161
|
-
```
|
|
147
|
+
**See [`CLAUDE.md`](CLAUDE.md) for complete module structure (19 modules).**
|
|
148
|
+
|
|
149
|
+
Key directories:
|
|
150
|
+
|
|
151
|
+
- `src/exness_data_preprocess/` — Source modules (DuckDB + ClickHouse backends)
|
|
152
|
+
- `tests/` — Test suite (48 tests)
|
|
153
|
+
- `docs/` — Documentation hub
|
|
154
|
+
- `.mise.toml` — Validation and tooling tasks
|
|
155
|
+
- `pyproject.toml` — Package configuration (SSoT for version via semantic-release)
|
|
162
156
|
|
|
163
157
|
### Adding New Features
|
|
164
158
|
|
|
165
159
|
When adding new features:
|
|
166
160
|
|
|
167
|
-
1. **Add implementation** in appropriate module (
|
|
168
|
-
2. **Add tests** in corresponding test file
|
|
161
|
+
1. **Add implementation** in appropriate module (see CLAUDE.md Module Structure)
|
|
162
|
+
2. **Add tests** in corresponding test file under `tests/`
|
|
169
163
|
3. **Update API exports** in `__init__.py` if needed
|
|
170
|
-
4. **Update
|
|
164
|
+
4. **Update CLAUDE.md** with module links if adding new modules
|
|
171
165
|
5. **Add docstrings** following Google style
|
|
172
166
|
|
|
173
167
|
Example docstring:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: exness-data-preprocess
|
|
3
|
-
Version: 1.1
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: Professional Exness forex tick data preprocessing with optimal compression (Parquet Zstd-22) and DuckDB OHLC generation. Provides efficient storage (9% smaller than ZIP) with lossless precision and direct queryability.
|
|
5
5
|
Project-URL: Homepage, https://github.com/terrylica/exness-data-preprocess
|
|
6
6
|
Project-URL: Documentation, https://github.com/terrylica/exness-data-preprocess#readme
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: accepted
|
|
3
|
+
date: 2025-12-10
|
|
4
|
+
decision-maker: Terry Li
|
|
5
|
+
consulted:
|
|
6
|
+
[
|
|
7
|
+
Config-Discovery-Agent,
|
|
8
|
+
ClickHouse-Connection-Agent,
|
|
9
|
+
Skill-Reference-Agent,
|
|
10
|
+
ClickHouse-Pattern-Agent,
|
|
11
|
+
Mise-Pattern-Agent,
|
|
12
|
+
]
|
|
13
|
+
research-method: 9-agent-parallel-dctl
|
|
14
|
+
clarification-iterations: 2
|
|
15
|
+
perspectives: [SSoT-Configuration, DeveloperExperience, BackwardCompatibility]
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# ADR: ClickHouse Pydantic Config Integration
|
|
19
|
+
|
|
20
|
+
**Design Spec**: [Implementation Spec](/docs/design/2025-12-10-clickhouse-pydantic-config/spec.md)
|
|
21
|
+
|
|
22
|
+
## Context and Problem Statement
|
|
23
|
+
|
|
24
|
+
The `exness-data-preprocess` package has ClickHouse integration for tick data storage, but lacks:
|
|
25
|
+
|
|
26
|
+
1. **Database client configuration** - No DBeaver connection config generation
|
|
27
|
+
2. **SSoT for connection parameters** - Environment variables are scattered, not centralized in mise `[env]`
|
|
28
|
+
3. **Inconsistent SSL handling** - Uses `CLICKHOUSE_SECURE` (boolean) instead of canonical `CLICKHOUSE_MODE` (local/cloud) pattern
|
|
29
|
+
|
|
30
|
+
The `clickhouse-pydantic-config` skill from cc-skills provides a canonical pattern for generating DBeaver configs from Pydantic v2 models using mise as SSoT.
|
|
31
|
+
|
|
32
|
+
### Before/After
|
|
33
|
+
|
|
34
|
+
**Before**: Scattered configuration, no DBeaver integration
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
┌────────────────────┐
|
|
38
|
+
│ Code Defaults │
|
|
39
|
+
│ (hardcoded) │ ─┐
|
|
40
|
+
└────────────────────┘ │
|
|
41
|
+
│ │
|
|
42
|
+
│ port=8123 │ db='exness'
|
|
43
|
+
▼ ▼
|
|
44
|
+
┌────────────────────────────────────────┐
|
|
45
|
+
│ clickhouse_client.py │
|
|
46
|
+
└────────────────────────────────────────┘
|
|
47
|
+
▲ ▲
|
|
48
|
+
│ CLICKHOUSE_SECURE │ CLICKHOUSE_HOST
|
|
49
|
+
│ │
|
|
50
|
+
┌────────────────────┐ │
|
|
51
|
+
│ Env Vars │ │
|
|
52
|
+
│ (scattered) │ ─┘
|
|
53
|
+
└────────────────────┘
|
|
54
|
+
┌────────────────────┐
|
|
55
|
+
│ DBeaver │
|
|
56
|
+
│ (manual setup) │
|
|
57
|
+
└────────────────────┘
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
<details>
|
|
61
|
+
<summary>graph-easy source (before.dot)</summary>
|
|
62
|
+
|
|
63
|
+
```dot
|
|
64
|
+
digraph before {
|
|
65
|
+
rankdir=TB;
|
|
66
|
+
env_vars [label="Env Vars\n(scattered)"];
|
|
67
|
+
code_defaults [label="Code Defaults\n(hardcoded)"];
|
|
68
|
+
clickhouse_client [label="clickhouse_client.py"];
|
|
69
|
+
env_vars -> clickhouse_client [label="CLICKHOUSE_SECURE"];
|
|
70
|
+
env_vars -> clickhouse_client [label="CLICKHOUSE_HOST"];
|
|
71
|
+
code_defaults -> clickhouse_client [label="port=8123"];
|
|
72
|
+
code_defaults -> clickhouse_client [label="db='exness'"];
|
|
73
|
+
dbeaver [label="DBeaver\n(manual setup)"];
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
</details>
|
|
78
|
+
|
|
79
|
+
**After**: mise `[env]` as SSoT, DBeaver config generation
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
┌────────────────────────────┐
|
|
83
|
+
│ .mise.toml [env] │
|
|
84
|
+
│ (SSoT) │
|
|
85
|
+
└────────────────────────────┘
|
|
86
|
+
│
|
|
87
|
+
│ CLICKHOUSE_*
|
|
88
|
+
▼
|
|
89
|
+
┌──────────────────────┐ ┌────────────────────────────┐
|
|
90
|
+
│ clickhouse_client.py │ validated config │ ClickHouseConnection │
|
|
91
|
+
│ │ ◀────────────────── │ (Pydantic v2) │
|
|
92
|
+
└──────────────────────┘ └────────────────────────────┘
|
|
93
|
+
│
|
|
94
|
+
│ model fields
|
|
95
|
+
▼
|
|
96
|
+
┌────────────────────────────┐
|
|
97
|
+
│ generate_dbeaver_config.py │
|
|
98
|
+
└────────────────────────────┘
|
|
99
|
+
│
|
|
100
|
+
│ generates
|
|
101
|
+
▼
|
|
102
|
+
┌────────────────────────────┐
|
|
103
|
+
│ .dbeaver/data-sources.json │
|
|
104
|
+
└────────────────────────────┘
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
<details>
|
|
108
|
+
<summary>graph-easy source (after.dot)</summary>
|
|
109
|
+
|
|
110
|
+
```dot
|
|
111
|
+
digraph after {
|
|
112
|
+
rankdir=TB;
|
|
113
|
+
mise_env [label=".mise.toml [env]\n(SSoT)"];
|
|
114
|
+
pydantic [label="ClickHouseConnection\n(Pydantic v2)"];
|
|
115
|
+
clickhouse_client [label="clickhouse_client.py"];
|
|
116
|
+
dbeaver_script [label="generate_dbeaver_config.py"];
|
|
117
|
+
dbeaver_json [label=".dbeaver/data-sources.json"];
|
|
118
|
+
mise_env -> pydantic [label="CLICKHOUSE_*"];
|
|
119
|
+
pydantic -> clickhouse_client [label="validated config"];
|
|
120
|
+
pydantic -> dbeaver_script [label="model fields"];
|
|
121
|
+
dbeaver_script -> dbeaver_json [label="generates"];
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
</details>
|
|
126
|
+
|
|
127
|
+
## Research Summary
|
|
128
|
+
|
|
129
|
+
| Agent Perspective | Key Finding | Confidence |
|
|
130
|
+
| --------------------- | ------------------------------------------------------------------------------------------------------ | ---------- |
|
|
131
|
+
| Config-Discovery | `.mise.toml` has `[env]` section but no CLICKHOUSE\_\* vars; existing `config.py` has Pydantic pattern | High |
|
|
132
|
+
| ClickHouse-Connection | Current code uses `CLICKHOUSE_SECURE` for SSL; port 8123 for HTTP; database default is `exness` | High |
|
|
133
|
+
| Skill-Reference | Canonical model uses `CLICKHOUSE_MODE` (local/cloud) with mode-aware validation; scripts at `scripts/` | High |
|
|
134
|
+
| ClickHouse-Pattern | Three skills form a chain: cloud-management → pydantic-config → architect | High |
|
|
135
|
+
| Mise-Pattern | SSoT pattern: `[env]` section → scripts read via `os.environ.get()` with defaults | High |
|
|
136
|
+
|
|
137
|
+
## Decision Log
|
|
138
|
+
|
|
139
|
+
| Decision Area | Options Evaluated | Chosen | Rationale |
|
|
140
|
+
| ---------------- | --------------------------------------- | ------------------------------------ | --------------------------------------------- |
|
|
141
|
+
| SSL Config | CLICKHOUSE_SECURE vs CLICKHOUSE_MODE | Hybrid (MODE + SECURE fallback) | Backward compatibility for existing scripts |
|
|
142
|
+
| Script Location | inline mise task, src/ module, scripts/ | `scripts/generate_dbeaver_config.py` | Canonical pattern from cc-skills |
|
|
143
|
+
| Database Default | `default` vs `exness` | `exness` | Match existing codebase convention |
|
|
144
|
+
| Connection Scope | Single mode vs Both local+cloud | Single per invocation | Canonical pattern; `--mode` flag for override |
|
|
145
|
+
|
|
146
|
+
### Trade-offs Accepted
|
|
147
|
+
|
|
148
|
+
| Trade-off | Choice | Accepted Cost |
|
|
149
|
+
| -------------- | -------------- | -------------------------------------- |
|
|
150
|
+
| MODE vs SECURE | Hybrid support | Slightly more complex connection logic |
|
|
151
|
+
| PEP 723 script | Standalone | Script not part of installed package |
|
|
152
|
+
|
|
153
|
+
## Decision Drivers
|
|
154
|
+
|
|
155
|
+
- **SSoT Principle**: All configurable values should live in `.mise.toml` `[env]` section
|
|
156
|
+
- **Developer Experience**: Zero-friction local setup, DBeaver integration
|
|
157
|
+
- **Backward Compatibility**: Existing `CLICKHOUSE_SECURE` users should not break
|
|
158
|
+
- **Canonical Conformity**: Follow cc-skills patterns exactly
|
|
159
|
+
|
|
160
|
+
## Considered Options
|
|
161
|
+
|
|
162
|
+
- **Option A**: Full migration to CLICKHOUSE_MODE only
|
|
163
|
+
- Breaks existing scripts using CLICKHOUSE_SECURE
|
|
164
|
+
|
|
165
|
+
- **Option B**: Keep CLICKHOUSE_SECURE only, skip MODE
|
|
166
|
+
- Deviates from canonical cc-skills pattern
|
|
167
|
+
|
|
168
|
+
- **Option C**: Hybrid - CLICKHOUSE_MODE primary, CLICKHOUSE_SECURE fallback ← Selected
|
|
169
|
+
- Best of both worlds: canonical pattern + backward compatibility
|
|
170
|
+
|
|
171
|
+
## Decision Outcome
|
|
172
|
+
|
|
173
|
+
Chosen option: **Option C (Hybrid)**, because it adopts the canonical `CLICKHOUSE_MODE` pattern from cc-skills while maintaining backward compatibility for any existing automation using `CLICKHOUSE_SECURE`.
|
|
174
|
+
|
|
175
|
+
## Synthesis
|
|
176
|
+
|
|
177
|
+
**Convergent findings**: All agents agreed on using mise `[env]` as SSoT, scripts at `scripts/`, and Pydantic v2 models.
|
|
178
|
+
|
|
179
|
+
**Divergent findings**: Existing code uses `CLICKHOUSE_SECURE`; canonical skill uses `CLICKHOUSE_MODE`.
|
|
180
|
+
|
|
181
|
+
**Resolution**: Implement hybrid support - MODE takes precedence when set, SECURE as fallback for backward compatibility.
|
|
182
|
+
|
|
183
|
+
## Consequences
|
|
184
|
+
|
|
185
|
+
### Positive
|
|
186
|
+
|
|
187
|
+
- DBeaver config generation with zero manual setup
|
|
188
|
+
- mise `[env]` becomes SSoT for all ClickHouse connection parameters
|
|
189
|
+
- Follows canonical cc-skills pattern for maintainability
|
|
190
|
+
- Backward compatible with existing CLICKHOUSE_SECURE usage
|
|
191
|
+
|
|
192
|
+
### Negative
|
|
193
|
+
|
|
194
|
+
- Slightly more complex SSL detection logic in `clickhouse_client.py`
|
|
195
|
+
- Additional script file to maintain (`scripts/generate_dbeaver_config.py`)
|
|
196
|
+
|
|
197
|
+
## Architecture
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
┌──────────────────────┐ ┌────────────────────────────┐ ┌──────────────────────┐ ┌───────────────────┐
|
|
201
|
+
│ .mise.toml │ env vars │ scripts/ │ instantiate │ ClickHouseConnection │ serialize │ .dbeaver/ │
|
|
202
|
+
│ [env] + [tasks] │ ──────────▶ │ generate_dbeaver_config.py │ ─────────────▶ │ Pydantic Model │ ───────────▶ │ data-sources.json │
|
|
203
|
+
└──────────────────────┘ └────────────────────────────┘ └──────────────────────┘ └───────────────────┘
|
|
204
|
+
│
|
|
205
|
+
│ env vars
|
|
206
|
+
▼
|
|
207
|
+
┌──────────────────────┐
|
|
208
|
+
│ clickhouse_client.py │
|
|
209
|
+
│ (MODE fallback) │
|
|
210
|
+
└──────────────────────┘
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
<details>
|
|
214
|
+
<summary>graph-easy source</summary>
|
|
215
|
+
|
|
216
|
+
```dot
|
|
217
|
+
digraph arch {
|
|
218
|
+
rankdir=LR;
|
|
219
|
+
mise [label=".mise.toml\n[env] + [tasks]"];
|
|
220
|
+
script [label="scripts/\ngenerate_dbeaver_config.py"];
|
|
221
|
+
model [label="ClickHouseConnection\nPydantic Model"];
|
|
222
|
+
client [label="clickhouse_client.py\n(MODE fallback)"];
|
|
223
|
+
dbeaver [label=".dbeaver/\ndata-sources.json"];
|
|
224
|
+
mise -> script [label="env vars"];
|
|
225
|
+
mise -> client [label="env vars"];
|
|
226
|
+
script -> model [label="instantiate"];
|
|
227
|
+
model -> dbeaver [label="serialize"];
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
</details>
|
|
232
|
+
|
|
233
|
+
## References
|
|
234
|
+
|
|
235
|
+
- [clickhouse-pydantic-config skill](/Users/terryli/eon/cc-skills/plugins/devops-tools/skills/clickhouse-pydantic-config/)
|
|
236
|
+
- [mise-configuration skill](/Users/terryli/eon/cc-skills/plugins/itp/skills/mise-configuration/)
|
|
237
|
+
- [ADR: mise env centralized config](/docs/adr/2025-12-08-mise-env-centralized-config.md) (if exists)
|
exness_data_preprocess-1.2.1/docs/adr/diagrams/2025-12-10-clickhouse-pydantic-config-after.dot
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// After: mise [env] as SSoT, DBeaver config generation
|
|
2
|
+
digraph after {
|
|
3
|
+
rankdir=TB;
|
|
4
|
+
|
|
5
|
+
// SSoT
|
|
6
|
+
mise_env [label=".mise.toml [env]\n(SSoT)"];
|
|
7
|
+
|
|
8
|
+
// Pydantic Model
|
|
9
|
+
pydantic [label="ClickHouseConnection\n(Pydantic v2)"];
|
|
10
|
+
|
|
11
|
+
// Consumers
|
|
12
|
+
clickhouse_client [label="clickhouse_client.py"];
|
|
13
|
+
dbeaver_script [label="generate_dbeaver_config.py"];
|
|
14
|
+
dbeaver_json [label=".dbeaver/data-sources.json"];
|
|
15
|
+
|
|
16
|
+
// Relationships
|
|
17
|
+
mise_env -> pydantic [label="CLICKHOUSE_*"];
|
|
18
|
+
pydantic -> clickhouse_client [label="validated config"];
|
|
19
|
+
pydantic -> dbeaver_script [label="model fields"];
|
|
20
|
+
dbeaver_script -> dbeaver_json [label="generates"];
|
|
21
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Architecture: Config flow from mise to DBeaver
|
|
2
|
+
digraph arch {
|
|
3
|
+
rankdir=LR;
|
|
4
|
+
|
|
5
|
+
// Layers
|
|
6
|
+
mise [label=".mise.toml\n[env] + [tasks]"];
|
|
7
|
+
script [label="scripts/\ngenerate_dbeaver_config.py"];
|
|
8
|
+
model [label="ClickHouseConnection\nPydantic Model"];
|
|
9
|
+
client [label="clickhouse_client.py\n(MODE fallback)"];
|
|
10
|
+
dbeaver [label=".dbeaver/\ndata-sources.json"];
|
|
11
|
+
|
|
12
|
+
// Flow
|
|
13
|
+
mise -> script [label="env vars"];
|
|
14
|
+
mise -> client [label="env vars"];
|
|
15
|
+
script -> model [label="instantiate"];
|
|
16
|
+
model -> dbeaver [label="serialize"];
|
|
17
|
+
}
|
exness_data_preprocess-1.2.1/docs/adr/diagrams/2025-12-10-clickhouse-pydantic-config-before.dot
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Before: Scattered configuration, no DBeaver integration
|
|
2
|
+
digraph before {
|
|
3
|
+
rankdir=TB;
|
|
4
|
+
|
|
5
|
+
// Sources
|
|
6
|
+
env_vars [label="Env Vars\n(scattered)"];
|
|
7
|
+
code_defaults [label="Code Defaults\n(hardcoded)"];
|
|
8
|
+
|
|
9
|
+
// Consumer
|
|
10
|
+
clickhouse_client [label="clickhouse_client.py"];
|
|
11
|
+
|
|
12
|
+
// Relationships
|
|
13
|
+
env_vars -> clickhouse_client [label="CLICKHOUSE_SECURE"];
|
|
14
|
+
env_vars -> clickhouse_client [label="CLICKHOUSE_HOST"];
|
|
15
|
+
code_defaults -> clickhouse_client [label="port=8123"];
|
|
16
|
+
code_defaults -> clickhouse_client [label="db='exness'"];
|
|
17
|
+
|
|
18
|
+
// Missing
|
|
19
|
+
dbeaver [label="DBeaver\n(manual setup)"];
|
|
20
|
+
}
|