clusteraudiencekit 5.9.2__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.
- clusteraudiencekit-5.9.2/.github/ISSUE_TEMPLATE/bug_report.md +39 -0
- clusteraudiencekit-5.9.2/.github/ISSUE_TEMPLATE/feature_request.md +27 -0
- clusteraudiencekit-5.9.2/.github/dependabot.yml +52 -0
- clusteraudiencekit-5.9.2/.github/workflows/ci.yml +48 -0
- clusteraudiencekit-5.9.2/.gitignore +54 -0
- clusteraudiencekit-5.9.2/.pre-commit-config.yaml +33 -0
- clusteraudiencekit-5.9.2/ARCHITECTURE.md +282 -0
- clusteraudiencekit-5.9.2/CHANGELOG.md +648 -0
- clusteraudiencekit-5.9.2/CONTRIBUTING.md +137 -0
- clusteraudiencekit-5.9.2/CONTRIBUTORS.md +14 -0
- clusteraudiencekit-5.9.2/Cargo.lock +2152 -0
- clusteraudiencekit-5.9.2/Cargo.toml +42 -0
- clusteraudiencekit-5.9.2/LICENSE +21 -0
- clusteraudiencekit-5.9.2/Makefile +40 -0
- clusteraudiencekit-5.9.2/PKG-INFO +440 -0
- clusteraudiencekit-5.9.2/PYPI_UPLOAD.md +110 -0
- clusteraudiencekit-5.9.2/README.md +390 -0
- clusteraudiencekit-5.9.2/ROADMAP.md +74 -0
- clusteraudiencekit-5.9.2/ROADMAP_HONEST.md +105 -0
- clusteraudiencekit-5.9.2/SECURITY.md +56 -0
- clusteraudiencekit-5.9.2/SECURITY_AUDIT.md +105 -0
- clusteraudiencekit-5.9.2/SQL_EXPORT.md +422 -0
- clusteraudiencekit-5.9.2/benches/benchmarks.rs +8 -0
- clusteraudiencekit-5.9.2/clusteraudiencekit/__init__.py +71 -0
- clusteraudiencekit-5.9.2/clusteraudiencekit/_multi_algorithm.py +304 -0
- clusteraudiencekit-5.9.2/clusteraudiencekit/clusteraudiencekit.pyi +76 -0
- clusteraudiencekit-5.9.2/clusteraudiencekit/error_messages.py +139 -0
- clusteraudiencekit-5.9.2/clusteraudiencekit/limits.py +107 -0
- clusteraudiencekit-5.9.2/clusteraudiencekit/logging_config.py +81 -0
- clusteraudiencekit-5.9.2/clusteraudiencekit/okf_segment_profiles.py +95 -0
- clusteraudiencekit-5.9.2/clusteraudiencekit/py.typed +0 -0
- clusteraudiencekit-5.9.2/clusteraudiencekit/validation.py +53 -0
- clusteraudiencekit-5.9.2/docs/CODE_OF_CONDUCT.md +9 -0
- clusteraudiencekit-5.9.2/docs/CONTRIBUTING.md +62 -0
- clusteraudiencekit-5.9.2/docs/WORKFLOW_INTEGRATION.md +475 -0
- clusteraudiencekit-5.9.2/docs/api-reference.md +503 -0
- clusteraudiencekit-5.9.2/docs/architecture.md +146 -0
- clusteraudiencekit-5.9.2/docs/comparison.md +159 -0
- clusteraudiencekit-5.9.2/docs/error-catalog.json +212 -0
- clusteraudiencekit-5.9.2/docs/getting-started-simple.md +264 -0
- clusteraudiencekit-5.9.2/docs/performance-comparison.md +382 -0
- clusteraudiencekit-5.9.2/docs/press-release.md +511 -0
- clusteraudiencekit-5.9.2/docs/troubleshooting.md +446 -0
- clusteraudiencekit-5.9.2/examples/basic_segmentation.py +70 -0
- clusteraudiencekit-5.9.2/examples/sql_export_example.py +286 -0
- clusteraudiencekit-5.9.2/examples/streaming_updates.py +50 -0
- clusteraudiencekit-5.9.2/install.sh +32 -0
- clusteraudiencekit-5.9.2/pyproject.toml +98 -0
- clusteraudiencekit-5.9.2/python/clusteraudiencekit/__init__.py +70 -0
- clusteraudiencekit-5.9.2/python/clusteraudiencekit/cli.py +359 -0
- clusteraudiencekit-5.9.2/python/clusteraudiencekit/clusteraudiencekit.pyi +76 -0
- clusteraudiencekit-5.9.2/python/clusteraudiencekit/server.py +212 -0
- clusteraudiencekit-5.9.2/rust-toolchain.toml +3 -0
- clusteraudiencekit-5.9.2/scripts/install-curl.sh +106 -0
- clusteraudiencekit-5.9.2/scripts/install-from-source.sh +64 -0
- clusteraudiencekit-5.9.2/scripts/install-pip.ps1 +29 -0
- clusteraudiencekit-5.9.2/scripts/install-pip.sh +31 -0
- clusteraudiencekit-5.9.2/src/engine/activation.rs +621 -0
- clusteraudiencekit-5.9.2/src/engine/activation_orchestrator.rs +481 -0
- clusteraudiencekit-5.9.2/src/engine/algorithms.rs +565 -0
- clusteraudiencekit-5.9.2/src/engine/b2b_governance.rs +1100 -0
- clusteraudiencekit-5.9.2/src/engine/b2b_segmentation.rs +559 -0
- clusteraudiencekit-5.9.2/src/engine/behavioral.rs +489 -0
- clusteraudiencekit-5.9.2/src/engine/churn_prediction.rs +583 -0
- clusteraudiencekit-5.9.2/src/engine/clustering.rs +67 -0
- clusteraudiencekit-5.9.2/src/engine/clv.rs +517 -0
- clusteraudiencekit-5.9.2/src/engine/cohorts.rs +516 -0
- clusteraudiencekit-5.9.2/src/engine/dashboard.rs +665 -0
- clusteraudiencekit-5.9.2/src/engine/drift_detection.rs +590 -0
- clusteraudiencekit-5.9.2/src/engine/governance.rs +568 -0
- clusteraudiencekit-5.9.2/src/engine/k_estimation.rs +382 -0
- clusteraudiencekit-5.9.2/src/engine/lifecycle.rs +477 -0
- clusteraudiencekit-5.9.2/src/engine/lookalike.rs +516 -0
- clusteraudiencekit-5.9.2/src/engine/metrics.rs +31 -0
- clusteraudiencekit-5.9.2/src/engine/mod.rs +111 -0
- clusteraudiencekit-5.9.2/src/engine/neural_networks.rs +828 -0
- clusteraudiencekit-5.9.2/src/engine/pattern_discovery.rs +1228 -0
- clusteraudiencekit-5.9.2/src/engine/platform_adapters.rs +573 -0
- clusteraudiencekit-5.9.2/src/engine/plugins.rs +516 -0
- clusteraudiencekit-5.9.2/src/engine/price_intelligence.rs +926 -0
- clusteraudiencekit-5.9.2/src/engine/privacy.rs +466 -0
- clusteraudiencekit-5.9.2/src/engine/profiling.rs +428 -0
- clusteraudiencekit-5.9.2/src/engine/quality_metrics.rs +451 -0
- clusteraudiencekit-5.9.2/src/engine/revenue_intelligence.rs +1185 -0
- clusteraudiencekit-5.9.2/src/engine/rfm.rs +462 -0
- clusteraudiencekit-5.9.2/src/engine/segment_intelligence.rs +1103 -0
- clusteraudiencekit-5.9.2/src/engine/segments.rs +422 -0
- clusteraudiencekit-5.9.2/src/engine/sql_export.rs +612 -0
- clusteraudiencekit-5.9.2/src/engine/streaming.rs +673 -0
- clusteraudiencekit-5.9.2/src/engine/temporal_analytics.rs +1101 -0
- clusteraudiencekit-5.9.2/src/engine/xgboost_models.rs +580 -0
- clusteraudiencekit-5.9.2/src/lib.rs +72 -0
- clusteraudiencekit-5.9.2/src/python.rs +96 -0
- clusteraudiencekit-5.9.2/src/streaming/mod.rs +27 -0
- clusteraudiencekit-5.9.2/src/utils/conversions.rs +24 -0
- clusteraudiencekit-5.9.2/src/utils/mod.rs +6 -0
- clusteraudiencekit-5.9.2/src/utils/validation.rs +40 -0
- clusteraudiencekit-5.9.2/tests/test_basic.py +53 -0
- clusteraudiencekit-5.9.2/tests/test_clustering.py +251 -0
- clusteraudiencekit-5.9.2/tests/test_performance.py +169 -0
- clusteraudiencekit-5.9.2/tests/test_sql_export.py +247 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug Report
|
|
3
|
+
about: Report a bug to help us improve
|
|
4
|
+
title: "[BUG] "
|
|
5
|
+
labels: bug
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Description
|
|
10
|
+
Briefly describe the bug.
|
|
11
|
+
|
|
12
|
+
## Steps to Reproduce
|
|
13
|
+
1. ...
|
|
14
|
+
2. ...
|
|
15
|
+
3. ...
|
|
16
|
+
|
|
17
|
+
## Expected Behavior
|
|
18
|
+
What should happen?
|
|
19
|
+
|
|
20
|
+
## Actual Behavior
|
|
21
|
+
What actually happened?
|
|
22
|
+
|
|
23
|
+
## Environment
|
|
24
|
+
- OS: [e.g. macOS, Linux, Windows]
|
|
25
|
+
- Python version: [e.g. 3.10]
|
|
26
|
+
- Library version: [e.g. 2.0.0]
|
|
27
|
+
|
|
28
|
+
## Minimal Example
|
|
29
|
+
```python
|
|
30
|
+
# Minimal code to reproduce the bug
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Error Message
|
|
34
|
+
```
|
|
35
|
+
# Paste full error traceback here
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Additional Context
|
|
39
|
+
Any other context about the issue?
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature Request
|
|
3
|
+
about: Suggest an idea to improve the project
|
|
4
|
+
title: "[FEATURE] "
|
|
5
|
+
labels: enhancement
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Problem Statement
|
|
10
|
+
Describe the problem this feature would solve.
|
|
11
|
+
|
|
12
|
+
## Proposed Solution
|
|
13
|
+
How should this feature work?
|
|
14
|
+
|
|
15
|
+
## Use Case
|
|
16
|
+
What use case does this solve?
|
|
17
|
+
|
|
18
|
+
## Example
|
|
19
|
+
```python
|
|
20
|
+
# Example of how this would be used
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Alternatives
|
|
24
|
+
Any alternative approaches you've considered?
|
|
25
|
+
|
|
26
|
+
## Additional Context
|
|
27
|
+
Any other context or screenshots?
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
# Rust dependencies (Cargo.toml)
|
|
4
|
+
- package-ecosystem: "cargo"
|
|
5
|
+
directory: "/"
|
|
6
|
+
schedule:
|
|
7
|
+
interval: "weekly"
|
|
8
|
+
day: "monday"
|
|
9
|
+
time: "03:00"
|
|
10
|
+
open-pull-requests-limit: 5
|
|
11
|
+
reviewers:
|
|
12
|
+
- "Mullassery"
|
|
13
|
+
labels:
|
|
14
|
+
- "dependencies"
|
|
15
|
+
- "rust"
|
|
16
|
+
commit-message:
|
|
17
|
+
prefix: "chore(deps):"
|
|
18
|
+
include: "scope"
|
|
19
|
+
|
|
20
|
+
# Python dependencies (pip/pyproject.toml)
|
|
21
|
+
- package-ecosystem: "pip"
|
|
22
|
+
directory: "/"
|
|
23
|
+
schedule:
|
|
24
|
+
interval: "weekly"
|
|
25
|
+
day: "monday"
|
|
26
|
+
time: "03:00"
|
|
27
|
+
open-pull-requests-limit: 5
|
|
28
|
+
reviewers:
|
|
29
|
+
- "Mullassery"
|
|
30
|
+
labels:
|
|
31
|
+
- "dependencies"
|
|
32
|
+
- "python"
|
|
33
|
+
commit-message:
|
|
34
|
+
prefix: "chore(deps):"
|
|
35
|
+
include: "scope"
|
|
36
|
+
|
|
37
|
+
# GitHub Actions
|
|
38
|
+
- package-ecosystem: "github-actions"
|
|
39
|
+
directory: "/"
|
|
40
|
+
schedule:
|
|
41
|
+
interval: "weekly"
|
|
42
|
+
day: "monday"
|
|
43
|
+
time: "03:00"
|
|
44
|
+
open-pull-requests-limit: 3
|
|
45
|
+
reviewers:
|
|
46
|
+
- "Mullassery"
|
|
47
|
+
labels:
|
|
48
|
+
- "dependencies"
|
|
49
|
+
- "ci"
|
|
50
|
+
commit-message:
|
|
51
|
+
prefix: "chore(ci):"
|
|
52
|
+
include: "scope"
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
name: Tests & Build
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, develop]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
rust-build:
|
|
11
|
+
name: Rust Build & Test
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- uses: dtolnay/rust-toolchain
|
|
17
|
+
|
|
18
|
+
- uses: Swatinem/rust-cache@v2
|
|
19
|
+
with:
|
|
20
|
+
workspaces: |
|
|
21
|
+
crates
|
|
22
|
+
core
|
|
23
|
+
python
|
|
24
|
+
|
|
25
|
+
- name: Build Rust
|
|
26
|
+
run: cargo build --release --all-features
|
|
27
|
+
|
|
28
|
+
- name: Test Rust
|
|
29
|
+
run: cargo test --release --all-features
|
|
30
|
+
|
|
31
|
+
python-tests:
|
|
32
|
+
name: Python Tests (Python ${{ matrix.python-version }})
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
strategy:
|
|
35
|
+
matrix:
|
|
36
|
+
python-version: ["3.10", "3.11", "3.12"]
|
|
37
|
+
steps:
|
|
38
|
+
- uses: actions/checkout@v4
|
|
39
|
+
|
|
40
|
+
- uses: actions/setup-python@v4
|
|
41
|
+
with:
|
|
42
|
+
python-version: ${{ matrix.python-version }}
|
|
43
|
+
|
|
44
|
+
- name: Install dependencies
|
|
45
|
+
run: pip install -e ".[dev]"
|
|
46
|
+
|
|
47
|
+
- name: Run pytest
|
|
48
|
+
run: pytest tests/ -v --tb=short
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.installed.cfg
|
|
21
|
+
*.egg
|
|
22
|
+
|
|
23
|
+
# Virtual environments
|
|
24
|
+
venv/
|
|
25
|
+
ENV/
|
|
26
|
+
env/
|
|
27
|
+
|
|
28
|
+
# IDE
|
|
29
|
+
.vscode/
|
|
30
|
+
.idea/
|
|
31
|
+
*.swp
|
|
32
|
+
*.swo
|
|
33
|
+
*~
|
|
34
|
+
.DS_Store
|
|
35
|
+
|
|
36
|
+
# Testing
|
|
37
|
+
.pytest_cache/
|
|
38
|
+
.coverage
|
|
39
|
+
htmlcov/
|
|
40
|
+
.tox/
|
|
41
|
+
|
|
42
|
+
# Build
|
|
43
|
+
target/
|
|
44
|
+
Cargo.lock
|
|
45
|
+
*.o
|
|
46
|
+
|
|
47
|
+
# Database
|
|
48
|
+
*.db
|
|
49
|
+
*.sqlite
|
|
50
|
+
*.sqlite3
|
|
51
|
+
|
|
52
|
+
# Temporary
|
|
53
|
+
.tmp/
|
|
54
|
+
*.local
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v4.5.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: trailing-whitespace
|
|
6
|
+
- id: end-of-file-fixer
|
|
7
|
+
- id: check-yaml
|
|
8
|
+
- id: check-added-large-files
|
|
9
|
+
args: ['--maxkb=500']
|
|
10
|
+
|
|
11
|
+
- repo: https://github.com/rust-lang/rust-clippy
|
|
12
|
+
rev: v1.77.0
|
|
13
|
+
hooks:
|
|
14
|
+
- id: clippy
|
|
15
|
+
args: ['--all-targets', '--', '-W', 'clippy::all']
|
|
16
|
+
|
|
17
|
+
- repo: https://github.com/rust-lang/rustfmt
|
|
18
|
+
rev: v1.7.0
|
|
19
|
+
hooks:
|
|
20
|
+
- id: rustfmt
|
|
21
|
+
|
|
22
|
+
- repo: https://github.com/psf/black
|
|
23
|
+
rev: 24.1.1
|
|
24
|
+
hooks:
|
|
25
|
+
- id: black
|
|
26
|
+
language_version: python3
|
|
27
|
+
|
|
28
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
29
|
+
rev: v0.2.0
|
|
30
|
+
hooks:
|
|
31
|
+
- id: ruff
|
|
32
|
+
args: ['--fix']
|
|
33
|
+
- id: ruff-format
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
# ClusterAudienceKit Architecture & Ecosystem Boundaries
|
|
2
|
+
|
|
3
|
+
## Mission
|
|
4
|
+
|
|
5
|
+
**Identify Who Matters**
|
|
6
|
+
|
|
7
|
+
Core Question: Which customers should we target?
|
|
8
|
+
|
|
9
|
+
## Core Responsibility
|
|
10
|
+
|
|
11
|
+
ClusterAudienceKit is **exclusively responsible** for:
|
|
12
|
+
|
|
13
|
+
- **Customer Segmentation** — RFM analysis, behavioral clustering
|
|
14
|
+
- **Audience Definition** — Rules, criteria, membership logic
|
|
15
|
+
- **Audience Calculation** — Computing audience membership
|
|
16
|
+
- **Audience Refresh** — Recalculating audience membership
|
|
17
|
+
- **Segment Hierarchy** — Parent/child segment relationships
|
|
18
|
+
- **Scoring Models** — Customer value, churn risk, engagement scores
|
|
19
|
+
- **Audience Analytics** — Segment performance, overlap analysis
|
|
20
|
+
|
|
21
|
+
## What We Do NOT Own
|
|
22
|
+
|
|
23
|
+
These belong to other products:
|
|
24
|
+
|
|
25
|
+
### ❌ Data Quality & Validation (StatGuardian)
|
|
26
|
+
- Schema validation
|
|
27
|
+
- Data freshness checks
|
|
28
|
+
- Drift detection
|
|
29
|
+
- Constraint enforcement
|
|
30
|
+
|
|
31
|
+
**Our role:** Assume input data is valid. Optionally require StatGuardian gates.
|
|
32
|
+
|
|
33
|
+
### ❌ Journey Orchestration (PyCustomerJourney)
|
|
34
|
+
- Journey definition
|
|
35
|
+
- Step execution
|
|
36
|
+
- Communications
|
|
37
|
+
- Attribution
|
|
38
|
+
|
|
39
|
+
**Our role:** Provide audiences. They activate journeys.
|
|
40
|
+
|
|
41
|
+
### ❌ Data Activation (PyReverseETL)
|
|
42
|
+
- Syncing to operational systems
|
|
43
|
+
- Destination management
|
|
44
|
+
- Sync orchestration
|
|
45
|
+
|
|
46
|
+
**Our role:** Define audiences. They sync membership.
|
|
47
|
+
|
|
48
|
+
### ❌ Query Optimization & Context Discovery (PyStreamMCP)
|
|
49
|
+
- Query planning for audience retrieval
|
|
50
|
+
- Intelligent data fetching
|
|
51
|
+
- Token/cost optimization
|
|
52
|
+
- Streaming retrieval
|
|
53
|
+
|
|
54
|
+
**Our role:** Use PyStreamMCP for efficient data ingestion and downstream member retrieval.
|
|
55
|
+
|
|
56
|
+
## Integration with PyStreamMCP
|
|
57
|
+
|
|
58
|
+
**IMPORTANT:** ClusterAudienceKit should use **PyStreamMCP** for:
|
|
59
|
+
|
|
60
|
+
### Ingestion (Data In)
|
|
61
|
+
```python
|
|
62
|
+
# ✅ CORRECT: Use PyStreamMCP for intelligent data retrieval
|
|
63
|
+
from pystreammcp import Discovery
|
|
64
|
+
|
|
65
|
+
# When building audiences from multiple sources:
|
|
66
|
+
discovery = Discovery.new(query_id="audience_ingestion")
|
|
67
|
+
sources = discovery.discover_sources() # Find optimal data
|
|
68
|
+
optimized = discovery.optimize_for_cost() # Efficient retrieval
|
|
69
|
+
|
|
70
|
+
# Use optimized context to build audience
|
|
71
|
+
audience = create_audience(
|
|
72
|
+
name="churn_risk",
|
|
73
|
+
criteria=optimized, # PyStreamMCP's optimized context
|
|
74
|
+
source_query=optimized
|
|
75
|
+
)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Member Retrieval (Data Out)
|
|
79
|
+
```python
|
|
80
|
+
# ✅ CORRECT: Use PyStreamMCP for efficient member retrieval
|
|
81
|
+
from pystreammcp import Agent
|
|
82
|
+
|
|
83
|
+
# When retrieving audience members with context:
|
|
84
|
+
agent = Agent(agent_id="audience_member_context")
|
|
85
|
+
context = agent.query("customer context for audience enrichment")
|
|
86
|
+
|
|
87
|
+
# Get members with optimized context
|
|
88
|
+
members = audience.get_members()
|
|
89
|
+
enriched_members = enrich_with_context(members, context) # Context from PyStreamMCP
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Why Use PyStreamMCP?
|
|
93
|
+
- **Intelligent Data Fetching:** Discover optimal data sources for audience building
|
|
94
|
+
- **Cost Optimization:** 60-75% reduction in token/data usage
|
|
95
|
+
- **Streaming Retrieval:** Progressive member retrieval for large audiences
|
|
96
|
+
- **Query Planning:** Handle complex multi-step audience logic
|
|
97
|
+
- **Token Efficiency:** Avoid redundant data fetches
|
|
98
|
+
|
|
99
|
+
**Do NOT rebuild these in ClusterAudienceKit:**
|
|
100
|
+
- Query planning
|
|
101
|
+
- Data source discovery
|
|
102
|
+
- Token optimization
|
|
103
|
+
- Streaming retrieval
|
|
104
|
+
- Cost estimation
|
|
105
|
+
|
|
106
|
+
## Architectural Principles
|
|
107
|
+
|
|
108
|
+
### 1. Segmentation First
|
|
109
|
+
|
|
110
|
+
ClusterAudienceKit owns segmentation logic. Everything else is delegated.
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
Customer Data
|
|
114
|
+
↓
|
|
115
|
+
PyStreamMCP (Discover & Optimize)
|
|
116
|
+
↓
|
|
117
|
+
Efficient Retrieval
|
|
118
|
+
↓
|
|
119
|
+
ClusterAudienceKit (Segmentation)
|
|
120
|
+
↓
|
|
121
|
+
Audiences
|
|
122
|
+
↓
|
|
123
|
+
PyReverseETL (Activate)
|
|
124
|
+
↓
|
|
125
|
+
Operational Systems
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### 2. No Validation Logic
|
|
129
|
+
|
|
130
|
+
```rust
|
|
131
|
+
// ❌ NOT OUR JOB
|
|
132
|
+
fn validate_data(data: &Data) -> Result<()> {
|
|
133
|
+
// Check schema
|
|
134
|
+
// Check freshness
|
|
135
|
+
// Check constraints
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// ✅ OUR JOB
|
|
139
|
+
fn create_audience(data: &Data) -> Result<Audience> {
|
|
140
|
+
// Segment data
|
|
141
|
+
// Calculate membership
|
|
142
|
+
// Return audience
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### 3. Flexible Input
|
|
147
|
+
|
|
148
|
+
Audiences can be built from:
|
|
149
|
+
- Warehouse tables
|
|
150
|
+
- Query results
|
|
151
|
+
- APIs
|
|
152
|
+
- Stream data
|
|
153
|
+
- Real-time events
|
|
154
|
+
|
|
155
|
+
But don't rebuild query logic—use PyStreamMCP.
|
|
156
|
+
|
|
157
|
+
## Module Structure
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
core/src/
|
|
161
|
+
├── lib.rs # Public exports
|
|
162
|
+
├── error.rs # Error types
|
|
163
|
+
├── audience.rs # Audience definition & membership
|
|
164
|
+
├── segment.rs # Segmentation logic
|
|
165
|
+
├── clustering/ # Clustering algorithms
|
|
166
|
+
│ ├── kmeans.rs
|
|
167
|
+
│ ├── rfm.rs
|
|
168
|
+
│ └── behavioral.rs
|
|
169
|
+
├── scoring/ # Scoring models
|
|
170
|
+
│ ├── churn_risk.rs
|
|
171
|
+
│ ├── lifetime_value.rs
|
|
172
|
+
│ └── engagement.rs
|
|
173
|
+
└── storage/ # Persistence
|
|
174
|
+
├── schema.rs
|
|
175
|
+
└── repository.rs
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Integration Points
|
|
179
|
+
|
|
180
|
+
### With PyStreamMCP (Ingestion)
|
|
181
|
+
|
|
182
|
+
```rust
|
|
183
|
+
// Use PyStreamMCP to discover optimal data sources
|
|
184
|
+
use pystreammcp::Discovery;
|
|
185
|
+
|
|
186
|
+
let discovery = Discovery::new(query_id);
|
|
187
|
+
let sources = discovery.discover_sources()?;
|
|
188
|
+
let optimized_query = discovery.optimize_for_cost()?;
|
|
189
|
+
|
|
190
|
+
// Build audience from optimized query
|
|
191
|
+
let audience = Audience::from_query(optimized_query);
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### With PyStreamMCP (Member Retrieval)
|
|
195
|
+
|
|
196
|
+
```rust
|
|
197
|
+
// Use PyStreamMCP to efficiently retrieve member context
|
|
198
|
+
use pystreammcp::Agent;
|
|
199
|
+
|
|
200
|
+
let agent = Agent::new(agent_id);
|
|
201
|
+
let context = agent.query("member context")?;
|
|
202
|
+
|
|
203
|
+
// Enrich members with context
|
|
204
|
+
members.enrich_with(context);
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### With StatGuardian
|
|
208
|
+
|
|
209
|
+
```rust
|
|
210
|
+
// Optionally validate input data
|
|
211
|
+
use statguardian::ValidationGate;
|
|
212
|
+
|
|
213
|
+
Audience {
|
|
214
|
+
validation_gate: Option<ValidationGate>,
|
|
215
|
+
// Only build audience if validation passes
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### With PyReverseETL
|
|
220
|
+
|
|
221
|
+
```rust
|
|
222
|
+
// PyReverseETL syncs audience membership
|
|
223
|
+
sync_to_destination(
|
|
224
|
+
audience=&audience,
|
|
225
|
+
destination="salesforce",
|
|
226
|
+
)?;
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### With PyCustomerJourney
|
|
230
|
+
|
|
231
|
+
```rust
|
|
232
|
+
// PyCustomerJourney launches journeys for audience members
|
|
233
|
+
launch_journey(
|
|
234
|
+
audience_members=&audience.get_members(),
|
|
235
|
+
journey="churn_prevention",
|
|
236
|
+
)?;
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Testability
|
|
240
|
+
|
|
241
|
+
Each boundary is enforced through:
|
|
242
|
+
|
|
243
|
+
1. **Module privacy** — Query/validation/journey modules don't exist
|
|
244
|
+
2. **Type system** — Can't express query logic in our types
|
|
245
|
+
3. **Documentation** — Explicit "use PyStreamMCP" statements
|
|
246
|
+
4. **Integration tests** — Test against PyStreamMCP/StatGuardian APIs
|
|
247
|
+
|
|
248
|
+
## Philosophy
|
|
249
|
+
|
|
250
|
+
ClusterAudienceKit is to customer segmentation what dbt is to transformation.
|
|
251
|
+
|
|
252
|
+
- dbt owns **transformation**, not validation
|
|
253
|
+
- Airflow owns **orchestration**, not transformation
|
|
254
|
+
- ClusterAudienceKit owns **segmentation**, not query optimization
|
|
255
|
+
|
|
256
|
+
Each product excels at its domain precisely because it doesn't try to own everything else.
|
|
257
|
+
|
|
258
|
+
PyStreamMCP handles query optimization so ClusterAudienceKit can focus entirely on segmentation.
|
|
259
|
+
|
|
260
|
+
## Outcome
|
|
261
|
+
|
|
262
|
+
When properly integrated:
|
|
263
|
+
|
|
264
|
+
```
|
|
265
|
+
Raw Data (Multiple Sources)
|
|
266
|
+
↓
|
|
267
|
+
PyStreamMCP optimizes retrieval
|
|
268
|
+
↓
|
|
269
|
+
Efficient Data Access
|
|
270
|
+
↓
|
|
271
|
+
ClusterAudienceKit segments
|
|
272
|
+
↓
|
|
273
|
+
Audience Membership
|
|
274
|
+
↓
|
|
275
|
+
PyReverseETL activates
|
|
276
|
+
↓
|
|
277
|
+
Operational Systems (CRM, Marketing, etc.)
|
|
278
|
+
↓
|
|
279
|
+
Customer Engagement
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Each product does one thing excellently.
|