Skip to content

Commit 81829ca

Browse files
Feat/app UI i18n insights contracts (#1262)
## Changes This PR adds substantially richer authoring UI, and overhauls the deployment story. At a high level: **Data-contract & AI rule generation** - Import ODCS v3.x data contracts and generate DQX rules (predefined, property-based, and natural-language) via a new `contract_rules_service` and `/v1/contract` route, including a dedicated "from contract" UI. - Natural-language (`type: text`) expectations are generated through the app's ChatDatabricks Foundation Model path (no dspy/Spark needed in-container). - Reference-table checks (`foreign_key`, `has_valid_schema`) are now authored in the single-table editor with a table picker; schema-validation gets its own editor and mutual-exclusion handling for `expected_schema` vs `ref_table`. **UI features** - Internationalization (English, Spanish, Italian, Portuguese-BR) with a language selector and locale-parity test. - Insights dashboard is now hosted persistently so the embedded Lakeview iframe no longer reloads on every navigation; expandable labels UI; component reorganisation (`apx/` → `layout/`); regenerated API client (orval). **Deployment & docs** - Updated DEPLOYMENT.md / DEVELOPMENT.md (CLI v1.4.0+ gate, one-button `postgres_roles`, bind workflow) and removed duplicated content. ### Linked issues <!-- DOC: Link issue with a keyword: close, closes, closed, fix, fixes, fixed, resolve, resolves, resolved. See https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword --> Resolves #.. ### Tests <!-- How is this tested? Please see the checklist below and also describe any other relevant tests --> Added backend unit suites for the Lakebase executor, Postgres/Delta migration runners, contract rule generation, discovery DDL, dry-run dispatch, app scheduler lease, quarantine filtering, lint policy, and i18n locale parity. `make app-test` (658 passing) and `make test` (1160 passing) are green, along with `make fmt` and `make app-check`. - [x] manually tested - [x] added unit tests - [ ] added integration tests - [ ] added end-to-end tests - [ ] added performance tests ### Documentation and Demos <!-- Any user facing changes require documentation and demos update --> - [ ] added/updated demos - [x] added/updated docs - [x] added/updated agent skills --------- Co-authored-by: Marcin Wojtyczka <marcin.wojtyczka@databricks.com>
1 parent 7dcc54b commit 81829ca

94 files changed

Lines changed: 18370 additions & 4531 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Makefile

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,33 @@ app-test: ## Run app backend pytest suite (K=<expr> filter, COV=1 for coverage)
179179

180180
##@ App deploy (require PROFILE=<databricks-profile>; most also need TARGET=<bundle-target>)
181181

182+
# Minimum Databricks CLI version required to deploy. The ``postgres_roles``
183+
# resource in ``app/databricks.yml`` (one-button Lakebase provisioning) was
184+
# added in CLI v1.4.0 (https://github.com/databricks/cli/pull/5467); older
185+
# CLIs reject the unknown field at ``bundle validate`` with a confusing
186+
# error deep inside the deploy. Fail fast here with an actionable message.
187+
DATABRICKS_MIN_VERSION := 1.4.0
188+
189+
# Preflight: assert the CLI exists and is new enough. Used as a prerequisite
190+
# of app-deploy / app-bind so the version gate runs before any build or
191+
# network call. The sort -V trick: the smallest of {MIN, installed} equals
192+
# MIN exactly when installed >= MIN (handles 1.10 > 1.4 unlike a string sort).
193+
app-check-cli: ## Verify the Databricks CLI meets the minimum version for deploy
194+
@command -v databricks >/dev/null 2>&1 || \
195+
{ echo "ERROR: 'databricks' CLI not found on PATH. Install: https://docs.databricks.com/dev-tools/cli/install.html"; exit 1; }
196+
@ver=$$(databricks --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1); \
197+
if [ -z "$$ver" ]; then \
198+
echo "ERROR: could not parse a version from 'databricks --version'."; exit 1; \
199+
fi; \
200+
if [ "$$(printf '%s\n%s\n' "$(DATABRICKS_MIN_VERSION)" "$$ver" | sort -V | head -1)" != "$(DATABRICKS_MIN_VERSION)" ]; then \
201+
echo "ERROR: Databricks CLI v$$ver is too old; v$(DATABRICKS_MIN_VERSION)+ is required to deploy DQX Studio."; \
202+
echo " app/databricks.yml uses the 'postgres_roles' resource (one-button Lakebase),"; \
203+
echo " which older CLIs reject at 'bundle validate' with an unknown-field error."; \
204+
echo " Upgrade: brew upgrade databricks (or https://docs.databricks.com/dev-tools/cli/install.html)"; \
205+
exit 1; \
206+
fi; \
207+
echo "✓ Databricks CLI v$$ver (>= $(DATABRICKS_MIN_VERSION))"
208+
182209
# Grant Unity Catalog permissions after bundle deploy.
183210
#
184211
# Usage: make app-grant-permissions PROFILE=my-profile
@@ -216,7 +243,7 @@ app-grant-permissions: ## Run post-deploy GRANTs (called by app-deploy; standalo
216243
# to ``make app-deploy`` — the bind step reads the resolved bundle
217244
# variables to know which instance/schema name to bind to, so an
218245
# override applied only at deploy time would bind the wrong resource.
219-
app-bind: ## Adopt pre-existing UC schemas / volume / Lakebase into bundle (run ONCE per workspace)
246+
app-bind: app-check-cli ## Adopt pre-existing UC schemas / volume / Lakebase into bundle (run ONCE per workspace)
220247
@test -n "$(PROFILE)" || (echo "Usage: make app-bind PROFILE=<databricks-profile> TARGET=<bundle-target>"; exit 1)
221248
@test -n "$(TARGET)" || (echo "Usage: make app-bind PROFILE=<databricks-profile> TARGET=<bundle-target>"; exit 1)
222249
app/scripts/bind_resources.sh -p $(PROFILE) -t $(TARGET) $(if $(BUNDLE_VARS),-- $(BUNDLE_VARS))
@@ -245,10 +272,17 @@ app-bind: ## Adopt pre-existing UC schemas / volume / Lakebase into bundle (run
245272
# after a manual delete (the deploy errors out with "Instance name is
246273
# not unique" otherwise). Per-deploy CLI overrides keep ``databricks.yml``
247274
# clean.
248-
app-deploy: app-build ## Build, deploy bundle, grant permissions, and start app
275+
#
276+
# FORCE=1 appends ``--force`` to ``bundle deploy``. Use it when the deploy
277+
# aborts because a resource was modified in the workspace UI since the last
278+
# deploy (e.g. "dashboard ... has been modified remotely") — ``--force``
279+
# overwrites the remote copy with the bundle's local definition. This DROPS
280+
# any in-UI edits, so only set it once you've confirmed the local version is
281+
# the one you want to ship.
282+
app-deploy: app-check-cli app-build ## Build, deploy bundle, grant permissions, and start app (FORCE=1 to overwrite remote edits)
249283
@test -n "$(PROFILE)" || (echo "Usage: make app-deploy PROFILE=<databricks-profile> TARGET=<bundle-target>"; exit 1)
250284
@test -n "$(TARGET)" || (echo "Usage: make app-deploy PROFILE=<databricks-profile> TARGET=<bundle-target>"; exit 1)
251-
cd app && databricks bundle deploy -p $(PROFILE) -t $(TARGET) $(BUNDLE_VARS)
285+
cd app && databricks bundle deploy -p $(PROFILE) -t $(TARGET) $(if $(FORCE),--force) $(BUNDLE_VARS)
252286
app/scripts/post_deploy_grants.sh -p $(PROFILE) -t $(TARGET) $(if $(BUNDLE_VARS),-- $(BUNDLE_VARS))
253287
cd app && databricks bundle run $(APP_NAME) -p $(PROFILE) -t $(TARGET) $(BUNDLE_VARS)
254288

@@ -294,4 +328,4 @@ fork-sync: ## Mirror a fork PR to a branch in the main repo for full CI (PR=<num
294328
./.github/scripts/fork-sync-pr.sh $(PR)
295329

296330
.DEFAULT: all
297-
.PHONY: help all clean dev lint fmt test integration e2e perf anomaly coverage combine-coverage docs-build docs-serve-dev docs-install docs-serve docs-clean app-install app-build app-start-dev app-stop-dev app-regen-api app-check app-test app-grant-permissions app-bind app-deploy fork-sync build lock-dependencies lock-app-dependencies
331+
.PHONY: help all clean dev lint fmt test integration e2e perf anomaly coverage combine-coverage docs-build docs-serve-dev docs-install docs-serve docs-clean app-install app-build app-start-dev app-stop-dev app-regen-api app-check app-test app-check-cli app-grant-permissions app-bind app-deploy fork-sync build lock-dependencies lock-app-dependencies

SECURITY.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Security Policy
2+
3+
## Reporting a Vulnerability
4+
5+
**Please do not report security vulnerabilities through public GitHub issues, discussions, or pull requests.**
6+
7+
If you believe you've found a security vulnerability in DQX (the library, the CLI, or the DQX Studio web application), report it privately through one of the following channels:
8+
9+
1. **GitHub Security Advisories (preferred)** — open a private advisory on the [DQX repository](https://github.com/databrickslabs/dqx/security/advisories/new). This keeps the report confidential until a fix is released.
10+
2. **Email** — if you cannot use GitHub Security Advisories, contact the Databricks Labs maintainers at [labs-oss@databricks.com](mailto:labs-oss@databricks.com) with `DQX SECURITY` in the subject line.
11+
12+
### What to include
13+
14+
To help us triage quickly, please include as much of the following as you can:
15+
16+
- A description of the issue and its potential impact.
17+
- Steps to reproduce (proof-of-concept code, sample input, or a minimal repro repo).
18+
- The affected version(s) of DQX and, if relevant, the Databricks Runtime version.
19+
- Any mitigations or workarounds you have identified.
20+
21+
We will acknowledge receipt within **5 business days** and provide a more detailed response within **10 business days** indicating our next steps. We aim to patch confirmed vulnerabilities in a timely manner and will coordinate disclosure with the reporter.
22+
23+
## Supported Versions
24+
25+
Security fixes are only guaranteed for the **latest minor release** on the [`main` branch](https://github.com/databrickslabs/dqx) and published on [PyPI](https://pypi.org/project/databricks-labs-dqx/). Please upgrade to the latest release before reporting an issue when possible.
26+
27+
## Scope
28+
29+
The following are in scope:
30+
31+
- The `databricks-labs-dqx` Python library and CLI.
32+
- The DQX Studio web application under `app/` (FastAPI backend + React frontend).
33+
- The task-runner Databricks Job under `app/tasks/`.
34+
- Example code in `demos/` (informational only — reports welcome but low priority).
35+
36+
Out of scope:
37+
38+
- Vulnerabilities in third-party dependencies that are better reported upstream.
39+
- Issues requiring a privileged user (e.g., workspace admin) to already be compromised.
40+
- Denial-of-service resulting from reasonable use of Databricks platform limits.
41+
42+
## Disclosure Policy
43+
44+
- We follow a **coordinated disclosure** process and will credit reporters in release notes unless they prefer anonymity.
45+
- We request that reporters give us a reasonable window (typically 90 days) to issue a fix before any public disclosure.

app/CLAUDE.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,17 @@ RBAC is enforced — routes use `require_role(*roles)` from `backend/dependencie
3232
2. **Business user adjusts existing rules** — load → edit → optional dry-run → save (creates new version + approval request)
3333
3. **Engineer reviews and approves rules** — review GUI/YAML → optional dry-run → configure checks storage → approve → export to Delta table
3434
4. **Engineer generates rules via profiler** — select table → configure sampling → run profiler → review candidates → save
35-
5. **User browses and discovers rules** — filter by table/domain/owner/status → view versions → compare → import/export
35+
5. **Engineer pins a schema contract** — single-table editor → pick target table → add a `has_valid_schema` check → expected schema as DDL or reference table → strict/compatible mode → dry-run → save
36+
6. **Data product owner imports rules** — Import rules page → pick **From DQX YAML** or **From data contract** tab → review preview → save drafts
37+
7. **User browses and discovers rules** — filter by table/domain/owner/status → view versions → compare → import/export
38+
39+
### Synthetic FQN convention (`__sql_check__/<name>`)
40+
41+
Per-table rules carry a real `table_fqn`. **Cross-table SQL checks** are the only rules without a single home table, so they use the synthetic prefix `__sql_check__/<name>` and bucket under the **Cross-table rules** group in the UI catalog and edit-router. The runner reads their query body from `arguments.sql_query` and builds the input view from it (SQL fast-path, `is_sql_check=True`).
42+
43+
Reference checks such as `has_valid_schema` and `foreign_key` are **per-table** — they carry a real `table_fqn`, are authored/edited in the single-table editor, group under their target table, and run through the standard row-level engine via the normal `create_view(table_fqn)` path. They are *not* synthetic and need no special dispatch.
44+
45+
The cross-table dispatch lives in `backend/routes/v1/dryrun.py` and `backend/services/scheduler_service.py`. If you add another table-less rule kind, follow the synthetic-FQN convention and update both dispatchers in lock-step.
3646

3747
## Internal Storage
3848

0 commit comments

Comments
 (0)