datasentry-ai 0.1.0__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.
- datasentry_ai-0.1.0/.github/workflows/ci.yml +105 -0
- datasentry_ai-0.1.0/.github/workflows/pages.yml +36 -0
- datasentry_ai-0.1.0/.github/workflows/publish.yml +39 -0
- datasentry_ai-0.1.0/.gitignore +32 -0
- datasentry_ai-0.1.0/.python-version +1 -0
- datasentry_ai-0.1.0/CHANGELOG.md +87 -0
- datasentry_ai-0.1.0/CONTRIBUTING.md +54 -0
- datasentry_ai-0.1.0/DataSentry AI /344/272/247/345/223/201/350/256/276/350/256/241/344/270/216/345/274/200/345/217/221 Prompt /345/256/214/346/225/264/347/211/210.md" +4671 -0
- datasentry_ai-0.1.0/DataSentry AI /344/272/247/345/223/201/350/256/276/350/256/241/344/270/216/345/274/200/345/217/221 Prompt.docx +0 -0
- datasentry_ai-0.1.0/DataSentry AI /344/272/247/345/223/201/350/256/276/350/256/241/344/270/216/345/274/200/345/217/221 Prompt.md" +2497 -0
- datasentry_ai-0.1.0/Dockerfile +17 -0
- datasentry_ai-0.1.0/LICENSE +202 -0
- datasentry_ai-0.1.0/Makefile +28 -0
- datasentry_ai-0.1.0/PKG-INFO +179 -0
- datasentry_ai-0.1.0/README.md +148 -0
- datasentry_ai-0.1.0/benchmarks/bench_scan.py +205 -0
- datasentry_ai-0.1.0/docker-compose.yml +9 -0
- datasentry_ai-0.1.0/docs/00-/350/256/276/350/256/241/350/243/201/345/206/263/350/256/260/345/275/225-ADR.md +1129 -0
- datasentry_ai-0.1.0/docs/01-/350/256/276/350/256/241/346/235/220/346/226/231-/344/270/200/350/207/264/346/200/247/346/243/200/346/237/245.md +163 -0
- datasentry_ai-0.1.0/docs/02-/350/256/276/350/256/241/346/235/220/346/226/231-/351/243/216/351/231/251/350/257/206/345/210/253.md +183 -0
- datasentry_ai-0.1.0/docs/03-/350/256/276/350/256/241/346/235/220/346/226/231-MVP-V1-/345/210/222/345/210/206.md +184 -0
- datasentry_ai-0.1.0/docs/04-/350/256/276/350/256/241/346/235/220/346/226/231-SQLite-Schema-/350/215/211/346/241/210.md +317 -0
- datasentry_ai-0.1.0/docs/DEVELOPMENT.md +427 -0
- datasentry_ai-0.1.0/docs/assets/logo.svg +18 -0
- datasentry_ai-0.1.0/docs/demo/orders-report.html +34 -0
- datasentry_ai-0.1.0/docs/demo/orders-report.html.png +0 -0
- datasentry_ai-0.1.0/docs/index.html +227 -0
- datasentry_ai-0.1.0/examples/demo/demo.py +167 -0
- datasentry_ai-0.1.0/examples/ecommerce/run_showcase.py +215 -0
- datasentry_ai-0.1.0/examples/plugins/example_detector.py +80 -0
- datasentry_ai-0.1.0/packages/core/README.md +39 -0
- datasentry_ai-0.1.0/packages/core/pyproject.toml +30 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/__init__.py +111 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/connectors/__init__.py +49 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/connectors/base.py +108 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/connectors/csv.py +312 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/connectors/duckdb.py +105 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/connectors/errors.py +19 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/connectors/file_based.py +209 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/connectors/jsonl.py +71 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/connectors/parquet.py +64 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/connectors/registry.py +55 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/connectors/spec.py +37 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/connectors/xlsx.py +109 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/contracts/__init__.py +24 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/contracts/exporters.py +330 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/detectors/__init__.py +15 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/detectors/base.py +120 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/detectors/common.py +156 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/detectors/cross_field.py +157 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/detectors/cross_table.py +220 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/detectors/datetime.py +343 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/detectors/initial/__init__.py +117 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/detectors/initial/anomaly_ml.py +204 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/detectors/initial/categorical.py +252 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/detectors/initial/formula.py +66 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/detectors/initial/missing.py +150 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/detectors/initial/numeric.py +302 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/detectors/initial/textual.py +407 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/detectors/initial/uniqueness.py +183 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/detectors/missingness.py +424 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/detectors/runner.py +228 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/detectors/safe_eval.py +255 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/detectors/textual_variants.py +300 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/drift/__init__.py +8 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/drift/engine.py +182 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/engine/__init__.py +16 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/engine/base.py +34 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/engine/duckdb.py +79 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/engine/fusion.py +193 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/engine/profiler.py +165 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/engine/sql_guard.py +23 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/llm/provider.py +66 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/models/__init__.py +118 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/models/audit.py +46 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/models/contract.py +89 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/models/detector.py +66 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/models/drift.py +47 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/models/enums.py +126 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/models/evidence.py +39 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/models/feedback.py +30 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/models/fingerprint.py +24 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/models/issue.py +49 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/models/llm.py +69 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/models/profile.py +79 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/models/quality.py +16 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/models/repair.py +94 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/models/rules.py +82 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/models/scan.py +112 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/models/validation.py +22 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/plugins.py +91 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/privacy/redactor.py +155 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/repair/__init__.py +5 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/repair/engine.py +455 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/reporting/__init__.py +100 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/reporting/html.py +230 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/reporting/junit.py +80 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/reporting/markdown.py +83 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/reporting/sarif.py +92 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/rules/engine.py +133 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/scoring/__init__.py +30 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/scoring/engine.py +138 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/scoring/gate.py +96 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/scoring/quality.py +137 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/scoring/weights.py +33 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/storage/__init__.py +15 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/storage/paths.py +47 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/storage/schema.py +343 -0
- datasentry_ai-0.1.0/packages/core/src/datasentry_core/storage/store.py +675 -0
- datasentry_ai-0.1.0/pyproject.toml +110 -0
- datasentry_ai-0.1.0/src/datasentry/__init__.py +7 -0
- datasentry_ai-0.1.0/src/datasentry/api.py +379 -0
- datasentry_ai-0.1.0/src/datasentry/cli.py +920 -0
- datasentry_ai-0.1.0/src/datasentry/client.py +414 -0
- datasentry_ai-0.1.0/src/datasentry/llm_providers.py +228 -0
- datasentry_ai-0.1.0/src/datasentry/mcp_server.py +310 -0
- datasentry_ai-0.1.0/src/datasentry/repair_ai.py +420 -0
- datasentry_ai-0.1.0/src/datasentry/rules_ai.py +381 -0
- datasentry_ai-0.1.0/src/datasentry/trends.py +89 -0
- datasentry_ai-0.1.0/src/datasentry/ui.py +307 -0
- datasentry_ai-0.1.0/tests/test_anomaly_ml.py +134 -0
- datasentry_ai-0.1.0/tests/test_api.py +167 -0
- datasentry_ai-0.1.0/tests/test_cli.py +527 -0
- datasentry_ai-0.1.0/tests/test_connectors.py +389 -0
- datasentry_ai-0.1.0/tests/test_connectors_extra.py +313 -0
- datasentry_ai-0.1.0/tests/test_contract_export.py +172 -0
- datasentry_ai-0.1.0/tests/test_core_models.py +426 -0
- datasentry_ai-0.1.0/tests/test_cross_field.py +93 -0
- datasentry_ai-0.1.0/tests/test_cross_table.py +286 -0
- datasentry_ai-0.1.0/tests/test_datetime.py +159 -0
- datasentry_ai-0.1.0/tests/test_demo.py +62 -0
- datasentry_ai-0.1.0/tests/test_detector_registry.py +156 -0
- datasentry_ai-0.1.0/tests/test_drift_engine.py +281 -0
- datasentry_ai-0.1.0/tests/test_drift_integration.py +114 -0
- datasentry_ai-0.1.0/tests/test_duckdb_connector.py +187 -0
- datasentry_ai-0.1.0/tests/test_ecommerce.py +68 -0
- datasentry_ai-0.1.0/tests/test_evidence_json.py +56 -0
- datasentry_ai-0.1.0/tests/test_executor.py +132 -0
- datasentry_ai-0.1.0/tests/test_fusion.py +261 -0
- datasentry_ai-0.1.0/tests/test_fuzzy_duplicate.py +159 -0
- datasentry_ai-0.1.0/tests/test_gate.py +101 -0
- datasentry_ai-0.1.0/tests/test_initial_detectors.py +369 -0
- datasentry_ai-0.1.0/tests/test_llm_ai.py +381 -0
- datasentry_ai-0.1.0/tests/test_mcp_server.py +207 -0
- datasentry_ai-0.1.0/tests/test_missingness.py +157 -0
- datasentry_ai-0.1.0/tests/test_paths.py +62 -0
- datasentry_ai-0.1.0/tests/test_plugins.py +150 -0
- datasentry_ai-0.1.0/tests/test_profiler.py +149 -0
- datasentry_ai-0.1.0/tests/test_quality.py +147 -0
- datasentry_ai-0.1.0/tests/test_repair_ai.py +254 -0
- datasentry_ai-0.1.0/tests/test_repair_cli.py +231 -0
- datasentry_ai-0.1.0/tests/test_repair_engine.py +201 -0
- datasentry_ai-0.1.0/tests/test_reporting.py +277 -0
- datasentry_ai-0.1.0/tests/test_rules_ai.py +486 -0
- datasentry_ai-0.1.0/tests/test_safe_eval.py +105 -0
- datasentry_ai-0.1.0/tests/test_scoring.py +138 -0
- datasentry_ai-0.1.0/tests/test_storage.py +215 -0
- datasentry_ai-0.1.0/tests/test_textual_variants.py +134 -0
- datasentry_ai-0.1.0/tests/test_trends.py +105 -0
- datasentry_ai-0.1.0/tests/test_ui.py +170 -0
- datasentry_ai-0.1.0/uv.lock +1447 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
timeout-minutes: 20
|
|
12
|
+
env:
|
|
13
|
+
PYTHON_VERSION: "3.12"
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Install uv
|
|
18
|
+
uses: astral-sh/setup-uv@v5
|
|
19
|
+
|
|
20
|
+
- name: Set up Python
|
|
21
|
+
uses: actions/setup-python@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: ${{ env.PYTHON_VERSION }}
|
|
24
|
+
|
|
25
|
+
- name: Install dependencies
|
|
26
|
+
run: uv sync --frozen
|
|
27
|
+
|
|
28
|
+
- name: 1 · ruff lint
|
|
29
|
+
run: uv run ruff check .
|
|
30
|
+
|
|
31
|
+
- name: 2 · ruff format check
|
|
32
|
+
run: uv run ruff format --check .
|
|
33
|
+
|
|
34
|
+
- name: 3 · mypy --strict (datasentry_core + datasentry)
|
|
35
|
+
run: uv run mypy packages/core/src/datasentry_core src/datasentry
|
|
36
|
+
|
|
37
|
+
- name: 4 · pytest + coverage gate (>=85%)
|
|
38
|
+
run: uv run pytest --cov=datasentry_core --cov-fail-under=85 --cov-report=term --cov-report=xml
|
|
39
|
+
|
|
40
|
+
- name: 5 · upload coverage artifact
|
|
41
|
+
uses: actions/upload-artifact@v4
|
|
42
|
+
with:
|
|
43
|
+
name: coverage-xml
|
|
44
|
+
path: coverage.xml
|
|
45
|
+
|
|
46
|
+
- name: 6 · M9 demo smoke (budget 180s)
|
|
47
|
+
run: uv run python examples/demo/demo.py --rows 2000
|
|
48
|
+
|
|
49
|
+
- name: 7 · benchmark (1e6 rows, <=60s gate)
|
|
50
|
+
run: uv run python benchmarks/bench_scan.py 1000000
|
|
51
|
+
|
|
52
|
+
- name: 8 · CLI smoke (scan + report + exit code)
|
|
53
|
+
run: |
|
|
54
|
+
set -e
|
|
55
|
+
TMP=$(mktemp -d)
|
|
56
|
+
uv run python - <<'EOF'
|
|
57
|
+
from pathlib import Path
|
|
58
|
+
from datasentry import DataSentry
|
|
59
|
+
import tempfile
|
|
60
|
+
p = Path(tempfile.mkdtemp()) / "d.csv"
|
|
61
|
+
p.write_text("id,name\n1,alice\n2,bob\n")
|
|
62
|
+
c = DataSentry(project=p.parent / "ws")
|
|
63
|
+
try:
|
|
64
|
+
run, _, _ = c.scan_file(p)
|
|
65
|
+
r = c.export_report(run.id)
|
|
66
|
+
assert r["scan"]["fingerprint"]["row_count"] == 2
|
|
67
|
+
finally:
|
|
68
|
+
c.close()
|
|
69
|
+
EOF
|
|
70
|
+
|
|
71
|
+
- name: 9 · API + UI smoke (container-free)
|
|
72
|
+
run: |
|
|
73
|
+
set -e
|
|
74
|
+
uv run python - <<'EOF'
|
|
75
|
+
from fastapi.testclient import TestClient
|
|
76
|
+
from datasentry.api import create_app
|
|
77
|
+
c = TestClient(create_app())
|
|
78
|
+
assert c.get("/health").json()["ok"] is True
|
|
79
|
+
assert c.get("/ui/").status_code == 200
|
|
80
|
+
print("api+ui smoke ok")
|
|
81
|
+
EOF
|
|
82
|
+
|
|
83
|
+
- name: 10 · artifact check (report files exist)
|
|
84
|
+
run: |
|
|
85
|
+
set -e
|
|
86
|
+
TMP=$(mktemp -d)
|
|
87
|
+
uv run python examples/demo/demo.py --rows 500 --out "$TMP" >/dev/null
|
|
88
|
+
test -f "$TMP/report.json"
|
|
89
|
+
test -f "$TMP/report.html"
|
|
90
|
+
test -f "$TMP/customers.csv"
|
|
91
|
+
echo "artifacts ok"
|
|
92
|
+
|
|
93
|
+
- name: 11 · wheel build + isolated install smoke (both packages)
|
|
94
|
+
run: |
|
|
95
|
+
set -e
|
|
96
|
+
uv build
|
|
97
|
+
uv build packages/core
|
|
98
|
+
SMOKE=$(mktemp -d)
|
|
99
|
+
uv venv "$SMOKE/venv"
|
|
100
|
+
uv pip install --python "$SMOKE/venv/bin/python" \
|
|
101
|
+
dist/datasentry_ai-*.whl dist/datasentry_core-*.whl
|
|
102
|
+
TMP=$(mktemp -d)
|
|
103
|
+
printf 'name,price\n" alice ",10\nbob,n/a\n' > "$TMP/d.csv"
|
|
104
|
+
"$SMOKE/venv/bin/datasentry" --project "$TMP/ws" scan "$TMP/d.csv" >/dev/null
|
|
105
|
+
"$SMOKE/venv/bin/datasentry" --version
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: Deploy GitHub Pages
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
pages: write
|
|
11
|
+
id-token: write
|
|
12
|
+
|
|
13
|
+
concurrency:
|
|
14
|
+
group: pages
|
|
15
|
+
cancel-in-progress: true
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
deploy:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
environment:
|
|
21
|
+
name: github-pages
|
|
22
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v4
|
|
25
|
+
|
|
26
|
+
- name: Configure Pages
|
|
27
|
+
uses: actions/configure-pages@v5
|
|
28
|
+
|
|
29
|
+
- name: Upload site (docs/)
|
|
30
|
+
uses: actions/upload-pages-artifact@v3
|
|
31
|
+
with:
|
|
32
|
+
path: docs
|
|
33
|
+
|
|
34
|
+
- name: Deploy to GitHub Pages
|
|
35
|
+
id: deployment
|
|
36
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
push:
|
|
6
|
+
tags:
|
|
7
|
+
- 'v*'
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
id-token: write
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
publish:
|
|
15
|
+
name: Build + publish wheels to PyPI
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
environment: pypi
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Install uv
|
|
22
|
+
uses: astral-sh/setup-uv@v5
|
|
23
|
+
|
|
24
|
+
- name: Set up Python
|
|
25
|
+
uses: actions/setup-python@v5
|
|
26
|
+
with:
|
|
27
|
+
python-version: '3.12'
|
|
28
|
+
|
|
29
|
+
- name: Build both packages
|
|
30
|
+
run: |
|
|
31
|
+
uv build
|
|
32
|
+
uv build packages/core
|
|
33
|
+
ls -la dist/
|
|
34
|
+
|
|
35
|
+
- name: Publish to PyPI
|
|
36
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
37
|
+
with:
|
|
38
|
+
packages-dir: dist/
|
|
39
|
+
skip-existing: true
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.venv/
|
|
6
|
+
dist/
|
|
7
|
+
build/
|
|
8
|
+
.coverage
|
|
9
|
+
htmlcov/
|
|
10
|
+
.pytest_cache/
|
|
11
|
+
.ruff_cache/
|
|
12
|
+
.mypy_cache/
|
|
13
|
+
hypothesis/
|
|
14
|
+
.hypothesis/
|
|
15
|
+
|
|
16
|
+
# Project data
|
|
17
|
+
.datasentry/
|
|
18
|
+
*.db
|
|
19
|
+
*.sqlite3
|
|
20
|
+
|
|
21
|
+
# Env / secrets
|
|
22
|
+
.env
|
|
23
|
+
credentials.json
|
|
24
|
+
|
|
25
|
+
# OS
|
|
26
|
+
.DS_Store
|
|
27
|
+
|
|
28
|
+
# Editors
|
|
29
|
+
.idea/
|
|
30
|
+
.vscode/
|
|
31
|
+
~$*
|
|
32
|
+
workspace/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
本项目的所有显著变更按时间倒序列出。格式基于
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),
|
|
5
|
+
版本号遵循 [Semantic Versioning](https://semver.org/lang/zh-CN/)。
|
|
6
|
+
|
|
7
|
+
## [0.1.0] - 2026-08-09
|
|
8
|
+
|
|
9
|
+
MVP 里程碑:九项硬性验收 M1–M9 全达成(36+ 检测器、融合评分、
|
|
10
|
+
质量门禁、修复闭环、报告引擎、Docker、CI 十阶段、M9 Demo)。
|
|
11
|
+
V1 收官:漂移引擎、跨表完整性、AI 修复候选、MCP 生态面、趋势 UI。
|
|
12
|
+
|
|
13
|
+
### 新增(Step 32–45,V1 收官)
|
|
14
|
+
|
|
15
|
+
- **Step 45**:跨扫描趋势 UI —— `/ui/trends` 质量分趋势页
|
|
16
|
+
(纯函数数据层 `trends.build_trends`,ADR-045)
|
|
17
|
+
- **Step 44**:AI 修复候选 —— `repair propose --ai`,LLM 在
|
|
18
|
+
检测器对应的操作白名单内生成操作/参数/理由(脱敏 + 审计 +
|
|
19
|
+
缓存,ADR-044)
|
|
20
|
+
- **Step 43**:MCP stdio 服务器 —— 零依赖 JSON-RPC 2.0,
|
|
21
|
+
`datasentry mcp` 7 工具供 LLM 代理调用(ADR-043)
|
|
22
|
+
- **Step 42**:模型异常检测 —— IsolationForest / LOF 单变量
|
|
23
|
+
离群(`ScanConfig.detector_params`,scikit-learn 依赖,
|
|
24
|
+
ADR-042)
|
|
25
|
+
- **Step 41**:模糊重复检测 —— 归一化分组(大小写/标点/全半角),
|
|
26
|
+
uniqueness Level 3(ADR-041)
|
|
27
|
+
- **Step 40**:跨表外键完整性 —— `Contract.references` +
|
|
28
|
+
`ForeignKeyViolationDetector`(DuckDB LEFT JOIN 孤儿行,
|
|
29
|
+
ADR-040)
|
|
30
|
+
- **Step 39**:漂移引擎 —— `drift compare/latest`,两历史扫描
|
|
31
|
+
schema/行数/分数/issue 分布四类信号(ADR-039)
|
|
32
|
+
- **Step 38**:DuckDB 文件连接器 —— `.duckdb` READ_ONLY ATTACH
|
|
33
|
+
+ `scan --table`(ADR-038)
|
|
34
|
+
- **Step 37**:契约导出 —— `contract export --as pandera|ge`
|
|
35
|
+
(ADR-037)
|
|
36
|
+
- **Step 36**:CI 报告导出 —— JUnit / SARIF 两格式(ADR-036)
|
|
37
|
+
- **Step 35**:契约门禁修复证据释放 —— gate 报告携带修复建议
|
|
38
|
+
(ADR-035)
|
|
39
|
+
- **Step 34**:电商订单域多文件场景演示(契约 + 门禁 + 修复闭环
|
|
40
|
+
真实化,ADR-034)
|
|
41
|
+
- **Step 33**:产品 README 用户优先重构 + 路线图(ADR-033)
|
|
42
|
+
- **Step 32**:发布工程 —— wheel 构建、元数据、changelog
|
|
43
|
+
(ADR-032)
|
|
44
|
+
|
|
45
|
+
### 新增(Step 25–31,V1 第一阶段收尾)
|
|
46
|
+
|
|
47
|
+
- **Step 31**:检测器插件 API v1 —— `load_plugin_detectors`
|
|
48
|
+
目录动态加载(Detector 协议发现)、`<workspace>/plugins/`
|
|
49
|
+
自动加载、CLI `datasentry detectors`(ADR-031)
|
|
50
|
+
- **Step 30**:危险规则批准安全阀门 —— `rules approve --file`
|
|
51
|
+
重跑预运行复核,dangerous 规则需 `--force` 才激活(ADR-030)
|
|
52
|
+
- **Step 29**:Ollama 原生 `/api/generate` 接入 + 超时重试统一
|
|
53
|
+
(`_post_with_retry` 共享辅助)(ADR-029)
|
|
54
|
+
- **Step 28**:自然语言 → 规则候选 —— propose 脱敏画像 → LLM
|
|
55
|
+
严格 JSON → 预运行报告 → 候选落库待批 → approve 转正;
|
|
56
|
+
`llm_cache` prompt 哈希复用(ADR-028)
|
|
57
|
+
- **Step 27**:LLM Provider 抽象(core 零网络接口)+
|
|
58
|
+
确定性 PII 脱敏管线 + 审计闭环 `llm status/invocations`
|
|
59
|
+
(ADR-027)
|
|
60
|
+
- **Step 26**:工程收尾 —— Apache-2.0 LICENSE、
|
|
61
|
+
CONTRIBUTING.md、Makefile、Dockerfile + compose、
|
|
62
|
+
CI 十阶段(ADR-026)
|
|
63
|
+
- **Step 25**:M9 Demo 单脚本(5000 行 5.4s,预算内可复现)
|
|
64
|
+
(ADR-025)
|
|
65
|
+
|
|
66
|
+
### 新增(Step 1–24,MVP 主体)
|
|
67
|
+
|
|
68
|
+
- 36+ 检测器:缺失模式族(4 核心)、日期时间族(6 核心)、
|
|
69
|
+
表示变体与编码(spelling/fullwidth/mojibake/invalid_numeric)、
|
|
70
|
+
跨字段规则(受限安全表达式求值,ADR-015)等
|
|
71
|
+
- 证据驱动融合 + 六维质量评分(27 章归一化,ADR-013)
|
|
72
|
+
- 质量门禁 `scan --fail-on`(22 章场景 C,ADR-014)
|
|
73
|
+
- 修复闭环:propose → preview → apply → rollback(15 章,
|
|
74
|
+
ADR-020)
|
|
75
|
+
- 报告引擎:JSON / Markdown / HTML 三形态(26 章)
|
|
76
|
+
- 多格式连接器:CSV / Parquet / JSONL / XLSX(7.1,ADR-019)
|
|
77
|
+
- 契约引擎(跨表/多文件约束,C-04)
|
|
78
|
+
- REST API(FastAPI 单工作区门面,ADR-023)+ Web UI
|
|
79
|
+
(服务端渲染五核心页,ADR-024)
|
|
80
|
+
- 性能基准:1e6 行双档判定(20.4,ADR-021/022)
|
|
81
|
+
|
|
82
|
+
### 工程
|
|
83
|
+
|
|
84
|
+
- Python >= 3.12,DuckDB 执行引擎(ADR-005/007)
|
|
85
|
+
- 门禁:ruff + mypy --strict + pytest 覆盖率 >= 85%
|
|
86
|
+
(当前 522 例,95%)
|
|
87
|
+
- Docker 一键启动(`datasentry-server` 入口)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# 贡献指南
|
|
2
|
+
|
|
3
|
+
欢迎为 DataSentry 贡献代码。本项目按《产品设计与开发 Prompt 完整版 v2.0》
|
|
4
|
+
的开发流程演进(Step 阶段 + 3 连绿门禁),所有改动遵循下述约定。
|
|
5
|
+
|
|
6
|
+
## 开发环境
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
uv sync # 安装依赖(Python 3.12+,uv 项目工作区)
|
|
10
|
+
make check # 门禁:lint + type + test(覆盖率 ≥ 85%)
|
|
11
|
+
make check-all # 门禁 + M9 Demo + 性能基准
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## 门禁(必须全绿方可提交)
|
|
15
|
+
|
|
16
|
+
| 目标 | 内容 |
|
|
17
|
+
| --- | --- |
|
|
18
|
+
| `make lint` | ruff check + ruff format --check |
|
|
19
|
+
| `make type` | mypy --strict(datasentry_core + datasentry,69+ 文件 0 错误) |
|
|
20
|
+
| `make test` | pytest 全套 + coverage 门禁(--cov-fail-under=85) |
|
|
21
|
+
| 3 连绿 | 提交前连续 3 次全量门禁通过(防 flaky) |
|
|
22
|
+
|
|
23
|
+
## 代码约定
|
|
24
|
+
|
|
25
|
+
- 类型标注:全量 mypy --strict(新代码必须通过严格类型检查)
|
|
26
|
+
- 风格:ruff 默认 + E/F/W/I/UP/B/SIM/RUF 规则集;100 列
|
|
27
|
+
- 全角标点豁免:中文报告/文案(RUF002/003 全局忽略;RUF001 按
|
|
28
|
+
per-file-ignores 豁免 benchmarks、examples/demo、ui.py)
|
|
29
|
+
- 测试:pytest + coverage;新增功能必须带测试,覆盖新代码路径
|
|
30
|
+
- ADR:架构级决策(数据模型、接口契约、跨包改动)须在
|
|
31
|
+
`docs/00-设计裁决记录-ADR.md` 追加 ADR 条目再实现
|
|
32
|
+
|
|
33
|
+
## 提交规范
|
|
34
|
+
|
|
35
|
+
- 单步单提交:一个 Step 的成果一次提交,消息含 Step 编号
|
|
36
|
+
(如 `feat: REST API single-workspace facade (Step 23, ADR-023)`)
|
|
37
|
+
- 禁止提交机密:密钥、令牌、客户数据一律不进仓库
|
|
38
|
+
- 提交前检查:`git status` + `git diff` 确认只含本步文件
|
|
39
|
+
|
|
40
|
+
## 新增检测器 / 规则
|
|
41
|
+
|
|
42
|
+
1. 在 `packages/core/src/datasentry_core/detectors/` 实现(含规则元数据)
|
|
43
|
+
2. 加入 DETECTOR_REGISTRY 与 BenchRunner 预算表(ADR-007)
|
|
44
|
+
3. 测试:detector 单测 + 集成回归(tests/test_integration.py 同款)
|
|
45
|
+
4. README 检测器表格更新计数(当前 36)
|
|
46
|
+
|
|
47
|
+
## 性能与基准
|
|
48
|
+
|
|
49
|
+
- `make bench`(benchmarks/bench_scan.py):1e6 行全量扫描 ≤ 60s 为验收档
|
|
50
|
+
- 引入新依赖(尤其是 C 扩展)须说明对扫描预算的影响
|
|
51
|
+
|
|
52
|
+
## 许可证
|
|
53
|
+
|
|
54
|
+
Apache-2.0。提交代码即表示同意以 Apache-2.0 许可发布您的贡献。
|