diff --git a/CLAUDE.md b/CLAUDE.md index dffe1f4610..85eb4c61a7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -72,6 +72,121 @@ When documenting a quality check rule, follow `contributing/check-content-templa 6. Anomaly Types (via include-markdown) 7. Example with: Objective, Sample Data table, Anomaly Explanation, Flowchart (mermaid), SQL query, Potential Violation Messages +### Page Structure + +Pages fall into a small set of named types. Each type has a consistent layout, set of icons, and naming convention. Apply these across the whole userguide; older pages that diverge should be migrated when touched. + +- **Overview** — top-level landing for a section. Title pattern: `# X Overview` (or just `# X` when only one exists). Uses cards (never tables) to link out. Links open in the same tab. +- **Getting Started** — top-level hub for a feature sub-tree. Title pattern: `# Getting Started with X`. Layout: intro paragraph, an optional hero/overview screenshot illustrating the feature, optional `!!! info "Permissions"`, then **H2 categories** (`## Deep Dive`, `## How-tos`, `## API & FAQ`) each with their own grid card block, separated by `---` HR dividers. Links open in the same tab. +- **Introduction** — sub-feature concept page inside a feature sub-tree. Lighter conceptual overview (Overview / Why this matters / high-level summary), ends with `## Next Steps` cards pointing to other Deep Dive pages. +- **How It Works** — detailed mechanics inside a Deep Dive sub-tree. Source of truth for defaults, edge cases, permissions, notifications, history, and references the Introduction provides a lighter take of. +- **Deep Dive pages are concept-only.** No screenshots, image references, asset folders, or `` placeholders. They explain how something works; screenshots belong to Getting Started and How-tos. One accepted exception (the Source Records viewer page) is flagged as temporary debt — do not extend it. +- **Examples** — production scenarios for a feature. Each scenario uses `## Scenario Title` + `**Context.**` + `**What happens.**` + `**Why it works.**`. +- **How-tos** — single action page (Create, Edit, Delete, Filter, etc.). Lead with cross-links to siblings + Deep Dive + API. Step 1 starts with the action verb (no "In Settings > X" location prefix). Document the happy path only — don't add cancel/close-modal tips. "Dropdown/modal appears" is a valid standalone step. Use generic "A success message appears" rather than literal UI message text. +- **API** — REST reference. Layout: intro with base URL + Bearer token mention, `!!! tip` linking to `/api/docs`, `!!! note "Permissions"` summary, then schema or field-reference section, then sections grouped by operation (Create / Update / Delete / Filter) with `**Endpoint:**` + `**Permission:**` + `??? example` collapsible cURL blocks per endpoint. End with `## Error responses` table and `## Related` list. +- **FAQ** — short Q&A grouped by H2 topic, with `#### Question?` per item. +- **Permissions** — table of actions × required permissions. + +**Naming rules:** +- Page titles use "Context + Type" — e.g., `Datastore Tags FAQ`, `Quality Check Ownership Introduction`. Sidebar labels stay short. +- The category formerly called "Managing" (H2, folder, nav, asset folder) is now "How-tos" going forward. +- API pages (not FAQ) include a `!!! tip` banner linking to `https://demo.qualytics.io/api/docs`. +- For DELETE/destructive actions, use the "Before You X" pattern: heading + intro + table of effects + irreversibility warning (only when the action is genuinely irreversible — verify first). +- When a page depends on another section, use a CTA admonition at the top, not cross-section cards. +- When documenting list/grid columns, document only columns with tooltips or click behavior; skip purely informational columns. +- **Reference card order**: when a Getting Started page (or any Reference grid) lists Troubleshooting alongside API and FAQ, the order in both the card grid and `mkdocs.yml` nav is **Troubleshooting, API, FAQ**. If only API and FAQ exist, keep API before FAQ. +- **Connector docs**: the connector logo sits inline inside the H1 at ~36px (`# ![](.../logo-.svg){ width="36" style="vertical-align: middle;" } Connector`), never as a centered hero. Every connector `add-source.md` has a top-level **Field reference** H2 separate from the **Steps** tutorials; both sections share the same `=== "New Connection"` / `=== "Existing Connection"` tabs. Inside each tab, field groups (Connection Properties, Secrets Management optional, Datastore Properties) are bold-text labels, not headings, to keep the page TOC clean. Tutorials become short (click, fill, test, finish) and link back to the Field reference. REF. numbering restarts per screenshot. Connectors that cannot be enrichment targets must not ship a per-connector `add-enrichment.md`; link to the generic enrichment pages instead. The `managing/api.md` order is Connection Fields → Create with New Connection (auth-method tabs when applicable) → Create with Existing Connection → Other Operations. + +### H1 Icons + +H1 titles use the pattern `# :material-X:{ .middle style="color: var(--q-brick)" } Title`. The brick color (`#B83200`) matches the Qualytics accent. + +| Page Type | MDI Icon | +|:---|:---| +| Overview | `book-alphabet` | +| Getting Started | `book-open-page-variant` | +| Introduction | `book-open-variant` | +| Examples | `text-box-edit-outline` | +| How It Works | `file-cog` | +| API | `api` | +| FAQ | `help-circle-outline` | +| Permissions | `shield-lock-outline` | +| Navigation | `compass` | +| Settings | `cog-outline` | + +For **feature pages**, use the same MDI icon the frontend uses for that feature (verify against the frontend repo's `origin/develop`). For **how-tos pages inside a feature sub-tree**, omit the H1 icon — the matching card in the parent hub carries the action icon, but the destination page itself uses a plain title. The `:material-X:` shortcode does NOT render inside mermaid blocks; use plain text labels there. + +### Card Icons + +Grid cards (`
`) use `:material-X:{ .lg .middle } **Card Title**`. The base rule is: **the card icon mirrors the destination page's H1 icon exactly.** If the destination H1 has an icon, the card uses the same icon; if the destination H1 has no icon, the card has no icon either. Do not add an icon to make the grid look uniform, and do not invent an icon on the destination H1 just so the card can have one. + +**Exception for how-tos cards.** Cards that link to how-tos pages (Create, Edit, Delete, Filter, etc.) can use standard action icons as a fallback when the destination has no frontend-defined icon — how-tos pages themselves use a plain H1 (per the H1 Icons rule above), but their cards in the parent hub can still carry an action icon: + +| Action | MDI Icon | +|:---|:---| +| Add / Create | `plus-circle` | +| Apply | `check-underline-circle` | +| Edit | `pencil-circle` | +| Remove (detach, unassign) | `minus-circle` | +| Delete (destroy the item) | `delete-circle` | +| Right Click Options | `mouse` | +| Keyboard Shortcuts | `keyboard` | +| Available Connectors | `view-list` | +| Link | `link-variant` | +| Unlink | `link-variant-off` | +| Bulk action | `dots-vertical-circle` | +| Troubleshooting | `tools` | + +**Remove vs Delete** are distinct: Remove = detach/unassign (item still exists elsewhere); Delete = destroy the item itself. The **inline icon inside steps** matches the UI (e.g., `**Edit :material-pencil-outline:**` when the UI uses a pencil), while the **card icon** is the standardized version (`pencil-circle`). + +### Inline Action Icons + +UI buttons referenced inline use the pattern `**Label :material-icon:**` — icon is inside the bold, no parentheses or backticks around the icon. Body icons get an explicit color override against the default theme color: `**Edit :material-pencil-outline:{ style="color: var(--md-default-fg-color)" }**`. Label by the action (Edit, Remove, Close, Bulk menu, Plus), not by the icon's shape — never write "the vertical ellipsis", "three dots", or "the X button". + +### Tables (Permission Matrices, Support Tables) + +Canonical positive / negative icons use **filled** for positive and **outline** for negative, always at `.lg` size: + +```markdown +:material-check-circle:{ .lg title="Allowed" } +:material-close-circle-outline:{ .lg title="Not allowed" } +``` + +- Positive cells: `mdi-check-circle` (filled) with `title="Allowed"`, `"Supported"`, `"Yes"`, or `"Containers only"`. +- Negative cells: `mdi-close-circle-outline` (outline) with `title="Not allowed"`, `"Not supported"`, `"No"`, or `"Push-only"`. +- Always include `.lg`. The default icon size is too small inside table cells. +- The global stylesheet auto-colors icons by their `title` attribute (using `var(--q-positive)` and `var(--q-negative)`). Do not add inline `style="color: ..."` for these and do not use `mdi-check` (no circle). State-indicator tables (UI badge color references) can keep inline color where the variable isn't appropriate. +- **Permission rows are explicit, not consolidated.** Permission matrices list every team permission as its own row even when 4 of 5 share identical "Not allowed" cells; showing each level side-by-side with the allowed level puts the restriction in front of the reader. +- **DRY tabs only when neutral reference.** When a page has per-entry-point tabs each embedding a table: extract the table only if it describes options of a shared UI surface (same everywhere; screenshot is the only variant). Keep the table inline when it affirms capability at each entry point — even when rows look identical, per-tab listing does capability-affirmation work. When in doubt, leave inline. + +### Language and Style + +- **Avoid em-dashes (`—`)** in user-facing docs (markdown body, headings, table cells, admonitions). They read as an AI tell. Rephrase with a period (split into two sentences), comma, parentheses, colon, or hyphen `-`. When refactoring an existing page, sweep for the em-dash and replace every occurrence. Also watch for other AI tells like "It's not just X, it's Y" constructions and overly polished transition phrases. The rule applies to anything the end reader sees, not to commit messages or internal notes. +- **No internal source, IDs, or jargon in docs.** Docs describe behavior, not implementation. Do not include: file paths from internal repos (`operation/list/index.vue`, `app/crud/...`), private repo URLs, internal symbol names (`statusIcon`, `OperationBadgeStatus`, `UserType.Internal`), architecture jargon ("Dramatiq", "RabbitMQ", "dataplane", "controlplane", "broker", "Spark", "fiber"), internal ticket IDs in body text (`QUA-XXXX` belongs in commits and PR descriptions only), or "Verified against the frontend source" phrases with explicit file/line citations. +- **Simplify language for non-technical readers.** Replace jargon (`rotated` → `changed`, `migrated`, `pre-populated` → `already filled in`, `reflects`) with plainer alternatives. +- **Deployment terminology**: use **"self-hosted"** and **"managed deployment"** (not SaaS / non-SaaS) throughout user-facing docs. +- **Terminology renames**: the product feature formerly called **Catalog** is now **Sync**. Do not use "Catalog" or lowercase "catalog" as a product term. Replace with "datastore sync", "inventory of containers", "schema discovery via Sync", etc. Generic data-engineering uses are fine; product references are not. +- **Rule type Sample Data tables**: highlight only the offending cell with `VALUE` (for array or multi-value violations, wrap the whole array literal). Add a short "What gets flagged" sentence noting the violation is per-field. Filter columns are scope, never highlighted. Replace older `` patterns when touching the page. +- **Link target**: Overview and Getting Started pages open links in the same tab (they are navigation hubs); all other pages use `{:target="_blank"}`. + +### Assets and Screenshots + +- **Mirror the nav.** The directory layout under `docs/assets/` mirrors `mkdocs.yml`. Shared images go in `shared/`. Restructuring the nav means moving the matching asset folders. +- **Step screenshots**: `step-NUMBER-description.png` (e.g., `step-1-open-modal.png`). +- **Reference screenshots** (used outside step flows): `description.png` (no `step-` prefix). +- **Tab-shared step screenshots**: when a step image is reused across tabs at different step numbers, keep its descriptive name in the page-specific folder. Don't move to `shared/`. +- **Getting Started pages can include screenshots.** A single hero/overview image at the top illustrating the feature is encouraged. Avoid step-by-step screenshots there — those belong to How-tos. +- **Screenshots are the source of truth.** Example values (IDs, JSON, etc.) on a page must match the same-page screenshot. Don't propose cross-page standardization of example values. +- **Never delete user-provided assets.** Treat anything under `docs/assets/` as authoritative; do not remove (including `.DS_Store`, `.gitkeep`) without an explicit instruction. + +### Review Checklist + +Every review pass and every consolidated review prompt must include a sensitive-info / backend-leak check: + +- No internal feature flags, internal route names, error strings from internal services, internal class or function names, credentials, or backend-only terms ("internal X user", `UserType.X`, internal queue/actor names) in user-facing pages. +- Internal flags exposed publicly via the API (e.g., `inferred`, `owner_id`) are fine to reference; backend-only terms are not. +- Verify against `origin/develop` of the relevant repo when in doubt. Default branch is `develop` for frontend/controlplane/dataplane; `main` for this userguide repo. + ### Spell Checking The repository uses `typos` via pre-commit for spell checking. Custom word allowances are in `.typos.toml`. Files in `docs/assets/`, `venv/`, and dotfiles are excluded. @@ -117,3 +232,44 @@ Additional tools that can be added to `.pre-commit-config.yaml` for catching mor - **markdownlint-cli2** - Catches malformed tables, inconsistent list formatting, missing blank lines around fences - **lychee** - Validates all links including images, anchors, and external URLs + +## Terminology + +### Team Permissions vs User Roles + +Two terminologies must not be mixed: + +- **User roles** (platform-level): `Member`, `Manager`, `Admin`. Always call these "role". +- **Team permissions** (datastore-level): `Reporter`, `Viewer`, `Drafter`, `Author`, `Editor`. Always call these "team permission" (or just "permission" when context makes it obvious). + +Write "the **Author** team permission on the datastore", not "the Author role". The Admin bypass admonition ("Users with the **Admin** role bypass...") stays as-is because Admin is a user role. Flag any " role" wording in existing pages as a finding. + +## Workflow + +### Validate against the remote, not local clones + +When validating doc claims against system behavior, fetch from the GitHub remotes on the default branch `develop`, not local clones: + +- `Qualytics/controlplane@develop` +- `Qualytics/frontend-app@develop` (remote is `frontend-app`; the local folder may be named `frontend`) +- `Qualytics/dataplane@develop` + +Use `gh api repos/Qualytics//contents/?ref=develop` for file reads and `gh search code --repo Qualytics/` for grep-style searches. Only fall back to local if remote access fails. Internal findings still must not appear in the doc body (see Language and Style). + +### Do not run mkdocs build or serve unprompted + +Never run `mkdocs build` or `mkdocs serve` during a session unless the user explicitly asks. Builds take ~40-50 seconds and flood the context with warning lists. The `mkdocs-warnings` pre-commit hook covers this on `git commit`. The same applies to running the `run` skill against this project. + +### Batch pre-commit at most once per session + +Run `pre-commit run` at most ONCE per multi-task session, as the final task. For single-edit or trivial fixes, skip it entirely; the user runs it manually before committing. Each run takes ~55-60 seconds and floods the context with warning output. + +### Pre-commit needs the venv + +Always activate the venv before committing in this repo: + +```bash +source venv/bin/activate && git commit ... +``` + +The `scripts/check-anchor-changes.py` hook uses Python 3.10+ union syntax (`str | None`). The system `python3` on macOS is 3.9, so without the venv the hook fails with `TypeError: unsupported operand type(s) for |: 'type' and 'NoneType'`. diff --git a/docs/assets/data-quality-checks/ownership/getting-started/ownership-section.png b/docs/assets/data-quality-checks/ownership/getting-started/ownership-section.png new file mode 100644 index 0000000000..d233fb675b Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/getting-started/ownership-section.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-1-checks-list.png b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-1-checks-list.png new file mode 100644 index 0000000000..30a7fb8fb3 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-1-checks-list.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-10-success.png b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-10-success.png new file mode 100644 index 0000000000..cfa4eee449 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-10-success.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-2-select-checks.png b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-2-select-checks.png new file mode 100644 index 0000000000..bd425a91c6 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-2-select-checks.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-3-bulk-menu-icon.png b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-3-bulk-menu-icon.png new file mode 100644 index 0000000000..ae20f3929a Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-3-bulk-menu-icon.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-4-menu-options.png b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-4-menu-options.png new file mode 100644 index 0000000000..013899873e Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-4-menu-options.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-5-edit-option.png b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-5-edit-option.png new file mode 100644 index 0000000000..af2f1a48a1 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-5-edit-option.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-6-bulk-modal.png b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-6-bulk-modal.png new file mode 100644 index 0000000000..180d020db5 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-6-bulk-modal.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-7-toggle-owner.png b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-7-toggle-owner.png new file mode 100644 index 0000000000..bbce145464 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-7-toggle-owner.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-8-user-list.png b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-8-user-list.png new file mode 100644 index 0000000000..037956540c Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-8-user-list.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-9-save-button.png b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-9-save-button.png new file mode 100644 index 0000000000..c5cf43753d Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-9-save-button.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-1-template-checks.png b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-1-template-checks.png new file mode 100644 index 0000000000..bef3cf9752 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-1-template-checks.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-10-success.png b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-10-success.png new file mode 100644 index 0000000000..28048a5620 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-10-success.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-2-select-checks.png b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-2-select-checks.png new file mode 100644 index 0000000000..ee467b149d Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-2-select-checks.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-3-bulk-menu-icon.png b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-3-bulk-menu-icon.png new file mode 100644 index 0000000000..8856ca6784 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-3-bulk-menu-icon.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-4-menu-options.png b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-4-menu-options.png new file mode 100644 index 0000000000..9d04ba0da4 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-4-menu-options.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-5-edit-option.png b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-5-edit-option.png new file mode 100644 index 0000000000..4eb07586f0 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-5-edit-option.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-6-bulk-modal.png b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-6-bulk-modal.png new file mode 100644 index 0000000000..cd052ff6a1 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-6-bulk-modal.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-7-toggle-owner.png b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-7-toggle-owner.png new file mode 100644 index 0000000000..c04f7f8e81 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-7-toggle-owner.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-8-user-list.png b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-8-user-list.png new file mode 100644 index 0000000000..6fdfcb109c Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-8-user-list.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-9-save-button.png b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-9-save-button.png new file mode 100644 index 0000000000..403bb73f83 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-9-save-button.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-1-options-icon.png b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-1-options-icon.png new file mode 100644 index 0000000000..f0780ede89 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-1-options-icon.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-2-options-menu.png b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-2-options-menu.png new file mode 100644 index 0000000000..cf97f02a4e Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-2-options-menu.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-3-edit-option.png b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-3-edit-option.png new file mode 100644 index 0000000000..f42e49bb3c Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-3-edit-option.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-4-edit-modal.png b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-4-edit-modal.png new file mode 100644 index 0000000000..5eaae86b77 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-4-edit-modal.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-5-owner-field.png b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-5-owner-field.png new file mode 100644 index 0000000000..1052e1fa47 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-5-owner-field.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-6-user-list.png b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-6-user-list.png new file mode 100644 index 0000000000..4401817224 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-6-user-list.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-7-owner-selected.png b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-7-owner-selected.png new file mode 100644 index 0000000000..4a315ba7c2 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-7-owner-selected.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-8-update-button.png b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-8-update-button.png new file mode 100644 index 0000000000..78c799bf56 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-8-update-button.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-9-success.png b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-9-success.png new file mode 100644 index 0000000000..55a99ca506 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-9-success.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-1-checks-list.png b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-1-checks-list.png new file mode 100644 index 0000000000..5e579910ee Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-1-checks-list.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-2-select-check.png b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-2-select-check.png new file mode 100644 index 0000000000..46ff07256f Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-2-select-check.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-3-edit-modal.png b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-3-edit-modal.png new file mode 100644 index 0000000000..cf52974efd Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-3-edit-modal.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-4-owner-field.png b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-4-owner-field.png new file mode 100644 index 0000000000..c7ca7d72e0 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-4-owner-field.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-5-user-list.png b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-5-user-list.png new file mode 100644 index 0000000000..58a1860eaf Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-5-user-list.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-6-owner-selected.png b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-6-owner-selected.png new file mode 100644 index 0000000000..e1b5dd6a79 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-6-owner-selected.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-7-update-button.png b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-7-update-button.png new file mode 100644 index 0000000000..90b4fb4104 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-7-update-button.png differ diff --git a/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-8-success.png b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-8-success.png new file mode 100644 index 0000000000..22dc1f1774 Binary files /dev/null and b/docs/assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-8-success.png differ diff --git a/docs/data-quality-checks/overview-of-a-check.md b/docs/data-quality-checks/overview-of-a-check.md index faf8627146..fefc95e5e8 100644 --- a/docs/data-quality-checks/overview-of-a-check.md +++ b/docs/data-quality-checks/overview-of-a-check.md @@ -1,4 +1,4 @@ -# Checks Overview +# :material-book-alphabet:{ .middle style="color: var(--q-brick)" } Checks Overview Checks in Qualytics are rules applied to data that ensure quality by validating accuracy, consistency, and integrity. Each check includes a data quality rule, along with filters, tags, tolerances, and notifications, allowing efficient management of data across tables and fields. diff --git a/docs/data-quality-checks/ownership/api.md b/docs/data-quality-checks/ownership/api.md new file mode 100644 index 0000000000..146042f7eb --- /dev/null +++ b/docs/data-quality-checks/ownership/api.md @@ -0,0 +1,158 @@ +# :material-api:{ .middle style="color: var(--q-brick)" } Quality Check Ownership API + +This page documents how to read and change the **Owner** of a quality check via the REST API. Ownership is exposed on the standard Quality Checks endpoints (there is no dedicated ownership route) through a single `owner_id` field on create/update payloads and query parameters on the list endpoints (`owner_id` on `GET /quality-checks`, `owner=true` on `GET /quality-checks/listing`). All endpoints share the base URL of your deployment (for example, `https://your-instance.qualytics.io/api`) and require a Bearer token. + +!!! tip + For complete API documentation, including request and response schemas, visit the [API docs](https://demo.qualytics.io/api/docs){:target="_blank"}. + +!!! note "Permissions" + All endpoints require the **Member** role. Reads need the **Viewer** team permission on the check's datastore; writes (create, update, bulk update) need the **Author** team permission. The user targeted by `owner_id` must independently have at least the **Drafter** team permission on the same datastore. + +## The `owner_id` field + +Every quality check carries a single owner. The API exposes it as `owner_id` on writes and as a nested `owner` object on reads. + +| Field | Type | Description | +| :--- | :--- | :--- | +| `owner_id` | `int` | The user ID of the check owner. On `POST`, defaults to the caller (or to the `Qualytics` user on [AI Managed (inferred) checks](deep-dive/how-it-works.md#defaults-at-creation-time){:target="_blank"}). On `PUT`/`PATCH`, omit (or send `null`) to leave the owner unchanged. The target user must have at least the **Drafter** team permission on the check's datastore. | + +??? example "Example `owner` field on a read response (abbreviated)" + + ```json + { + "id": 101, + "rule_type": "unique", + "inferred": false, + "owner": { + "id": 42, + "name": "Alice Lee", + "email": "alice@example.com" + } + } + ``` + +## Create + +### Create a check with an explicit owner + +**Endpoint:** `POST /api/quality-checks` + +**Permission:** Member role + **Author** team permission on the container's datastore. The target `owner_id` must have **Drafter** on the same datastore. + +Include `owner_id` in the create payload to set an explicit owner. Omit the field to let the platform default to the caller. + +??? example "Example request" + + ```bash + curl -X POST "https://your-instance.qualytics.io/api/quality-checks" \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "description": "Ensure C_NAME is unique in the CUSTOMER table", + "rule": "unique", + "fields": ["C_NAME"], + "container_id": 145, + "owner_id": 42 + }' + ``` + +## Update + +### Transfer ownership on a single check + +**Endpoint:** `PUT /api/quality-checks/{id}` + +**Permission:** Member role + **Author** team permission on the check's datastore. The target `owner_id` must have **Drafter** on the same datastore. + +Send `owner_id` set to the new owner's user ID. The previous owner is recorded in the check's history. + +The `PUT` endpoint requires `description`; include the check's current description (or a new one if you also want to update it) along with `owner_id`. + +??? example "Example request" + + ```bash + curl -X PUT "https://your-instance.qualytics.io/api/quality-checks/101" \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "description": "Ensure C_NAME is unique in the CUSTOMER table", + "owner_id": 42 + }' + ``` + +!!! warning "AI Managed conversion still applies" + For AI Managed (inferred) checks owned by Qualytics, editing any *assertion property* (`properties`, `coverage`, `filter`, or `fields`) in the same payload also transfers ownership to the editor and flips `inferred` from `true` to `false`. Sending `owner_id` without modifying any assertion property transfers ownership and keeps `inferred` as `true`. + +### Transfer ownership across many checks + +**Endpoint:** `PATCH /api/quality-checks` + +**Permission:** Member role + **Author** team permission on the datastore of every check in the request. The target `owner_id` must have **Drafter** on each of those datastores. + +Send a list of `{ id, owner_id }` entries; the same `owner_id` can be reused across entries to apply one owner to many checks. + +!!! note "Bulk is all-or-nothing" + If any entry references a check the caller cannot update (404 not found, missing **Author** on the datastore, or the target `owner_id` lacks **Drafter**), the entire request is rejected and no checks are updated. Retry with the offending entry removed. + +??? example "Apply the same owner to many checks" + + ```bash + curl -X PATCH "https://your-instance.qualytics.io/api/quality-checks" \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '[ + { "id": 101, "owner_id": 42 }, + { "id": 102, "owner_id": 42 }, + { "id": 103, "owner_id": 42 } + ]' + ``` + +## Filter + +### Filter checks by a specific owner + +**Endpoint:** `GET /api/quality-checks` + +**Permission:** Member role. Results are scoped to datastores the caller can see. + +Use the `owner_id` query parameter to narrow the list to checks owned by a specific user. Combine with the other list filters (status, tags, rule type, and so on) to scope further. + +??? example "List checks owned by user 42" + + ```bash + curl -X GET "https://your-instance.qualytics.io/api/quality-checks?owner_id=42" \ + -H "Authorization: Bearer YOUR_TOKEN" + ``` + +### List checks owned by the current user + +**Endpoint:** `GET /api/quality-checks/listing` + +**Permission:** Member role. + +The aggregated listing endpoint accepts `owner=true`, which scopes the result to checks owned by the user issuing the request. This is the same filter the UI uses for the **Owned** subtab. + +??? example "Equivalent of the Owned subtab" + + ```bash + curl -X GET "https://your-instance.qualytics.io/api/quality-checks/listing?owner=true&count_perspective=checks" \ + -H "Authorization: Bearer YOUR_TOKEN" + ``` + +## Error responses + +| Status | Description | +| :--- | :--- | +| `400 Bad Request` | A business-logic conflict prevents the operation (for example, attempting to change properties while the check status is invalid or discarded). | +| `401 Unauthorized` | Missing or invalid API token. | +| `403 Forbidden` | The caller lacks **Author** on the check's datastore, or the target `owner_id` lacks **Drafter** on the same datastore. | +| `404 Not Found` | The check ID or `owner_id` user does not exist. | +| `422 Unprocessable Entity` | The payload fails schema validation (for example, a required field such as `description` is missing on `PUT`, `owner_id` is not an integer, or `properties` contains an unrecognized key for the rule type). | + +## Related + +- [Introduction](deep-dive/introduction.md){:target="_blank"}: overview of ownership and the three transfer modes at a glance. +- [How It Works](deep-dive/how-it-works.md){:target="_blank"}: full mechanics: defaults, the three transfer modes in detail, permissions, notifications, history, and filtering. +- [Change Check Owner](how-tos/change-owner.md){:target="_blank"}: UI walkthrough that mirrors `PUT /api/quality-checks/{id}`. +- [Bulk Change Check Owner](how-tos/bulk-change-owner.md){:target="_blank"}: UI walkthrough that mirrors `PATCH /api/quality-checks`. +- [FAQ](faq.md){:target="_blank"}: short answers to the most common ownership questions. diff --git a/docs/data-quality-checks/ownership/deep-dive/examples.md b/docs/data-quality-checks/ownership/deep-dive/examples.md new file mode 100644 index 0000000000..4e22e48567 --- /dev/null +++ b/docs/data-quality-checks/ownership/deep-dive/examples.md @@ -0,0 +1,66 @@ +# :material-text-box-edit-outline:{ .middle style="color: var(--q-brick)" } Quality Check Ownership Examples + +Real-world scenarios that show how check ownership is typically used in production. Each example combines the same building blocks: defaults at creation, transfer modes, filtering, and notifications. + +## Onboarding a new data engineer + +**Context.** A new data engineer joins the team and is added to the **Customer Data** datastore with the **Drafter** team permission. They will gradually take over a set of AI Managed checks that have been running since the datastore was profiled, all still owned by the `Qualytics` user. + +**What happens.** + +1. The engineer opens the datastore's **Quality Checks** tab and applies the **Owner** filter, picking `Qualytics` from the top of the dropdown. The list narrows to every AI Managed check that no one has taken over. +2. For each check they review, they open the **Edit Check** form and change the **Owner** to themselves. The inline warning **"Once transferred, ownership cannot be returned to Qualytics"** appears in the dropdown. +3. After saving, the **Owner** filter is updated to their own user (via the **Owned** subtab) so they can keep a personal queue of the checks they are now responsible for. + +**Why it works.** AI Managed checks default to `Qualytics`, so they are easy to find by filter. The explicit transfer requires only the **Drafter** permission on the datastore for the new owner, which the engineer already has, and the **Author** permission for the user making the change. + +## Reassigning a teammate's checks + +**Context.** An engineer is rotating off the team. Their Authored checks on the **Orders** datastore need to move to a new owner before they lose access. + +**What happens.** + +1. The team lead opens **Explore > Checks**, applies the **Owner** filter, and picks the leaving engineer's name. The list narrows to every check they currently own. +2. The team lead selects all the checks via the row checkboxes. The selection toolbar shows the total count. +3. They open the **bulk menu :material-dots-vertical:{ style="color: var(--md-default-fg-color)" }** in the toolbar and click **Edit :material-square-edit-outline:{ style="color: var(--md-default-fg-color)" }**. The **Bulk Edit Checks** modal opens; they toggle on the **Owner** row and pick the new owner from the dropdown. +4. After **Save**, every check is updated to the new owner. Each check's **History** records the bulk change with the lead's name as the user who made it. +5. The new owner sees the checks under their **Owned** subtab on the next page load. + +**Why it works.** The **Owner** filter scopes the list to a single user before bulk selection, eliminating the risk of accidentally reassigning unrelated checks. The bulk endpoint replaces (not merges) the owner, which is the intended behavior in a handoff. + +## Coordinating edits with ownership notifications + +**Context.** Two engineers maintain a shared set of checks on the **Inventory** datastore. They want to know when the other person edits one of their checks so they can keep their downstream dashboards in sync. + +**What happens.** + +1. Each check is owned by one of the two engineers; ownership was assigned explicitly when the checks were authored. +2. When engineer A edits the **coverage** of a check owned by engineer B, the platform creates an **Ownership** in-app notification for engineer B: *"Engineer A updated a check you own"* (`#482` • Volumetrics). +3. Engineer B opens the notification, sees the change in the check's **History**, and updates their dashboard query the same day. + +**Why it works.** The notification fires whenever the updater is not the owner, so every cross-edit produces a signal. Self-edits stay silent, which keeps the notification feed focused on edits the owner did not make. + +## Auditing AI Managed checks before a compliance review + +**Context.** Ahead of a quarterly compliance review, the data platform team needs a clean inventory of which checks are still managed by `Qualytics` (and therefore subject to Profile refreshes) versus those that have been explicitly taken over. + +**What happens.** + +1. A team admin opens **Explore > Checks** and sets the **Owner** filter to `Qualytics`. The list shows every check still managed by `Qualytics` across all datastores they have access to. +2. They export the list (or call `GET /api/quality-checks?owner_id=`) and share it with the compliance reviewer. +3. The reviewer flags the subset that should be locked from Profile refreshes. For each flagged check, the admin opens the **Edit Check** form, transfers ownership to a named user, and saves. If any assertion property is also edited during the same save, the check converts to Authored; ownership transfer alone (no assertion changes) keeps `inferred: true` while attributing responsibility to a human owner. + +**Why it works.** The `Qualytics` user is treated like any other owner in the filter dropdown, so the audit becomes a single filter operation. The transfer-only path (without editing assertion properties) is the Explicit transfer flow documented in [How It Works · Explicit transfer](how-it-works.md#explicit-transfer-edit-form-or-bulk-update){:target="_blank"} and the [API · `owner_id` field notes](../api.md#the-owner_id-field){:target="_blank"}. + +## Draft promotion with automatic owner reassignment + +**Context.** A Drafter-level reviewer creates a quality check as a Draft for review by a senior engineer. The senior engineer holds the **Author** team permission; the Drafter does not. + +**What happens.** + +1. The Drafter authors the check and saves it as **Draft**. They are recorded as the owner because they created it. +2. The senior engineer opens the check, validates it, and flips the **Status** from **Draft** to **Active**. +3. Because the Drafter cannot manage an Active check, the **Drafter activation transfer** fires automatically: the owner is reassigned from the Drafter to the senior engineer at the same save. +4. The check's **History** records both events on the same timeline entry: the status change *and* the ownership reassignment. + +**Why it works.** Drafter activation transfer prevents an Active check from being stuck with an owner who cannot edit it. The pattern keeps the audit trail accurate: the senior engineer ends up as the responsible owner the moment the check goes live. diff --git a/docs/data-quality-checks/ownership/deep-dive/how-it-works.md b/docs/data-quality-checks/ownership/deep-dive/how-it-works.md new file mode 100644 index 0000000000..e4a53c19a5 --- /dev/null +++ b/docs/data-quality-checks/ownership/deep-dive/how-it-works.md @@ -0,0 +1,103 @@ +# :material-file-cog:{ .middle style="color: var(--q-brick)" } How Quality Check Ownership Works + +This page covers the behavior of the **Owner** field on a quality check in detail. For a lighter conceptual overview, see [Introduction](introduction.md){:target="_blank"}. For step-by-step actions, see [Change Check Owner](../how-tos/change-owner.md){:target="_blank"} and [Bulk Change Check Owner](../how-tos/bulk-change-owner.md){:target="_blank"}. + +## The field + +The **Owner** field on a quality check identifies a single user who is responsible for the check. Every check has exactly one owner at any time. The field appears in the Edit Check form, in the Bulk Edit Checks modal, in the filter panel of every check list, and in the check's **History**. + +Ownership is independent of the **last editor** of the check: editing a property does not automatically transfer ownership unless one of the specific transfer rules described below applies. + +## Defaults at creation time + +Who owns a check when it is created depends on how the check came into existence: + +- **AI Managed (inferred) checks** are owned by the `Qualytics` user. The user is rendered with the literal label `Qualytics` in every owner dropdown and filter, and is pinned at the top of the list. +- **Authored checks** default to the user who creates them. If the **Owner** dropdown in the Edit Check form is left unchanged, the current user is recorded as the owner on save. Authored checks can also be created with an explicit owner: any user with at least the **Drafter** team permission on the target container's datastore can be selected. + +The owner is always a single user. Setting "no owner" is not possible for Authored checks; for AI Managed checks, the owner stays `Qualytics` until one of the transfer rules below applies. + +## Transferring ownership + +Ownership can change in three ways. Two of them are explicit user actions; the third happens automatically when certain edits are saved. + +### Explicit transfer (Edit form or Bulk Update) + +A user with the **Author** team permission on the datastore can open an existing check, choose a different user from the **Owner** dropdown, and save. The new owner must have at least the **Drafter** permission on the same datastore, and users without that permission are not selectable. The same dropdown is available in the Bulk Edit Checks modal, which applies the chosen owner to every selected check in one save. + +!!! warning "Transfer away from Qualytics is one-way in the UI" + Once an AI Managed check's owner is transferred from `Qualytics` to a regular user, the Edit Check form disables `Qualytics` as a selectable owner. The inline warning **"Once transferred, ownership cannot be returned to Qualytics"** makes this explicit in the dropdown. + +### Implicit transfer (editing an AI Managed check) + +When an AI Managed check is still owned by `Qualytics` and a user edits any of its **assertion properties** (the rule-specific `properties` payload, `coverage`, `filter`, or `fields`), ownership transfers to the editor on save. The same edit flips `inferred` from `true` to `false` and converts the check to Authored, so future Profile runs no longer replace it. + +Editing organizational fields only (description, tags, additional metadata, status, anomaly message field) does **not** transfer ownership and does **not** convert the check. + +### Drafter activation transfer + +When a check is moved from **Draft** to **Active**, the platform verifies that the current owner has at least the **Author** permission required to manage an Active check. If the current owner does not have the **Author** permission, ownership is transferred to the user who activates the check. This prevents an Active check from being owned by a user who cannot edit it. + +## Permissions + +| Action | Required permission on the check's datastore | +| :--- | :--- | +| See the Owner field | Viewer | +| Be selectable as an owner | Drafter | +| Change the owner (explicit transfer) | Author | +| Activate a Draft check (may trigger transfer) | Author | + +The owner dropdown is populated with the users with at least the **Drafter** permission on the datastore. Users without that permission are filtered out and cannot be assigned ownership, even by an Author. See [Team Permissions](../../../settings/security/teams/team-permissions/overview.md){:target="_blank"} for the full permission matrix. + +## Notifications + +Whenever a check is updated, the platform creates an **Ownership** in-app notification for the user currently listed as owner, **unless** the updater is the owner. The notification has the form: + +> *{updater name}* updated a check you own +> +> `#{check id}` • *{rule title}* + +Clicking the notification opens the affected check. + +A few specifics: + +- **Self-edits do not notify.** Editing your own check does not generate a notification. +- **Checks owned by `Qualytics` never notify.** No in-app notification is created when the owner is the `Qualytics` user; updates on AI Managed checks are silent until ownership is transferred to a regular user. +- **Implicit and Drafter transfers do not notify.** When ownership changes as part of the same save that produced the notification trigger, the new owner does not receive a notification for that save. The next update by someone else does. + +See [In-App Notifications](../../../using-the-platform/web-app/top-right-menu/in-app-notifications/introduction.md){:target="_blank"} for how Ownership notifications appear in the bell-icon list alongside other notification types. + +## History tracking + +Every change to the owner is recorded in the check's **History** section, alongside property edits, coverage changes, filter updates, tag changes, and status transitions. The timeline shows: + +- **Who** made the change. +- **When** the change happened. +- **The previous owner and the new owner.** + +Implicit transfers (from `Qualytics` to a regular user) and Drafter activation transfers are surfaced explicitly, so it is clear when ownership moved automatically. + +## Owner, Default Anomaly Assignee, and Assignees + +Three related concepts are easy to mix up. Here is how they differ: + +| Concept | Lives on | Cardinality | What it does | +| :--- | :--- | :---: | :--- | +| **Owner** | Quality check | One user | The person responsible for the check itself. Used for filtering checks by owner and for ownership notifications. | +| **Default Anomaly Assignee** | Quality check | One user | The user that anomalies produced by the check are auto-assigned to at creation time. | +| **Assignees** | Anomaly | Many users | The users actually responsible for resolving the anomaly. Editable per anomaly. | + +The chain reads: a check has one owner and one default assignee; when the check produces an anomaly, that default seeds the anomaly's assignees list, which can then be expanded or narrowed independently. + + + + +## Filtering by owner + +You can narrow any check list to a specific owner in two ways: + +- **The Owner filter.** A dropdown in the filter panel that lists every user with at least the **Drafter** permission on the datastore, with the `Qualytics` entry pinned at the top. Selecting one user narrows the list to checks owned by that user. Available on every per-datastore check tab and on the global checks explorer. +- **The Owned subtab.** A one-click shortcut to "checks I own", available under both the **Active** and **Draft** parent tabs of every check list. Selecting it sets the owner filter to your user automatically. + +Both work alongside the other check filters (rule type, status, tags, coverage, etc.), so you can layer them. For example, combine "owned by me" with status `Active` to narrow the list to your live checks. diff --git a/docs/data-quality-checks/ownership/deep-dive/introduction.md b/docs/data-quality-checks/ownership/deep-dive/introduction.md new file mode 100644 index 0000000000..111f6aba11 --- /dev/null +++ b/docs/data-quality-checks/ownership/deep-dive/introduction.md @@ -0,0 +1,47 @@ +# :material-book-open-variant:{ .middle style="color: var(--q-brick)" } Quality Check Ownership Introduction + +## Overview + +Every quality check in Qualytics has a single **owner**: the user responsible for the check. Ownership is recorded directly on the check, shown as the **Owner** field in the UI and as the `owner` object on every API read. + +Ownership is the answer to a basic question that comes up in any data quality program: *who is responsible for this rule?* With that answer in place, the platform supports three workflows: + +- **Filtering by responsibility.** The check list has an **Owned** subtab that scopes the list to the current user, plus a per-user **Owner** filter for inspecting any teammate's checks. +- **In-app notifications.** When a teammate edits a check you own, you receive an **Ownership** notification linking back to the check. +- **Audit trail.** Every change to the owner is recorded in the check's **History**, alongside property edits and status transitions. + +## Why this matters + +A check without a clear owner is hard to maintain. Whoever opens it later cannot tell whether someone else is already responsible for it, who to ask about its intent, or whether tweaking it would step on another team member's work. Ownership turns that ambiguity into a concrete attribution and gives teammates a way to coordinate before making conflicting edits. + +Ownership also flags which checks are still managed by the platform. **AI Managed** checks start out owned by the `Qualytics` user. When a user edits one of its assertion properties (`properties`, `coverage`, `filter`, or `fields`), the owner changes to the editor and the platform stops managing the check. An Author can also explicitly transfer ownership without editing any assertion property; in that case the new owner is attributed but the check remains AI Managed until an assertion edit converts it to Authored. + +## The transfer modes at a glance + +Ownership changes in three ways. Each is documented in detail on [How It Works](how-it-works.md){:target="_blank"}: + +- **Explicit transfer.** A user with the **Author** team permission picks a new owner from the **Owner** dropdown in the Edit Check form, or from the Bulk Edit Checks modal when handling many checks at once. +- **Implicit transfer.** Editing an assertion property (`properties`, `coverage`, `filter`, or `fields`) on an AI Managed check moves ownership from `Qualytics` to the editor on the same save. +- **Drafter activation transfer.** When a **Draft** check is moved to **Active** and the current owner does not have the **Author** permission, ownership transfers to the user who activated it. This prevents an Active check from being owned by a user who cannot edit it. + +## Next Steps + +
+ +- :material-file-cog:{ .lg .middle } **How It Works** + + --- + + Full semantics: defaults, the three transfer modes in detail, permissions, notifications, history tracking, the comparison with anomaly assignees, and filtering. + + [:octicons-arrow-right-24: How It Works](how-it-works.md){:target="_blank"} + +- :material-text-box-edit-outline:{ .lg .middle } **Examples** + + --- + + Production scenarios that show ownership in action: onboarding, handoffs, notification-driven workflows, compliance audits, and Draft promotion. + + [:octicons-arrow-right-24: Examples](examples.md){:target="_blank"} + +
diff --git a/docs/data-quality-checks/ownership/faq.md b/docs/data-quality-checks/ownership/faq.md new file mode 100644 index 0000000000..312492fbac --- /dev/null +++ b/docs/data-quality-checks/ownership/faq.md @@ -0,0 +1,109 @@ +# :material-help-circle-outline:{ .middle style="color: var(--q-brick)" } Quality Check Ownership FAQ + +Common questions about the **Owner** field on quality checks. For an overview, see [Introduction](deep-dive/introduction.md){:target="_blank"}; for full behavior, see [How It Works](deep-dive/how-it-works.md){:target="_blank"}. + +## Defaults and creation + +#### Who owns a check by default? + +- **AI Managed (inferred) checks** are owned by the `Qualytics` user. +- **Authored checks** default to the user who creates them. If you create a check through the API and omit `owner_id`, the caller is recorded as the owner. + +#### Can a check have no owner? + +No. Every check has exactly one owner at any time. The Owner dropdown does not allow clearing the field, and the API keeps the current owner if `owner_id` is omitted or set to `null` on update. + +#### Can a check have more than one owner? + +No. Ownership is a single user. If you want shared responsibility, set a single owner and use the **Default Anomaly Assignee** field (also a single user) on the same check to seed the assignee list on anomalies; multiple users can then be added as anomaly assignees. + +## Transfers + +#### How do I transfer ownership of an AI Managed check? + +Open the check and pick a regular user from the **Owner** dropdown. The Edit Check form shows an inline warning when transferring away from `Qualytics`. Saving converts the check to Authored (`inferred: false`) only if you also edit an assertion property (`properties`, `coverage`, `filter`, or `fields`). Transferring ownership alone leaves `inferred` as `true`. + +#### Can I transfer ownership back to Qualytics? + +No. Once an AI Managed check's owner has been transferred to a regular user, it cannot be set back to `Qualytics`. The dropdown disables the `Qualytics` option in this case. + +#### Why did the owner change automatically when I edited a check? + +Two automatic transfers can fire on save: + +- **Implicit transfer.** If the check was still owned by `Qualytics` and you edited any assertion property (`properties`, `coverage`, `filter`, or `fields`), ownership moves to you. This is the same edit that converts the check to Authored. +- **Drafter activation transfer.** If the check moved from **Draft** to **Active** and the current owner does not have the **Author** team permission, ownership moves to the user who activated it. This prevents an Active check from being owned by a user who cannot edit it. + +#### I want to take a check from a teammate without editing anything. Is that possible? + +Yes. Open the **Edit Check** form, change the **Owner** to yourself, and save. This counts as an explicit transfer and is recorded in the check's **History**. You still need the **Author** team permission on the datastore. + +## Permissions + +#### Who can be selected as an owner? + +Any user with at least the **Drafter** team permission on the check's datastore. Users without that permission do not appear in the dropdown. + +#### Who can change the owner? + +Any user with the **Author** team permission on the check's datastore. The new owner must independently have the **Drafter** team permission on the same datastore. + +#### Can a user with only Viewer permission see who owns a check? + +Yes. The Owner field is visible to anyone who can see the check (Viewer or above). Only changing the owner requires the **Author** team permission. + +## Notifications + +#### Will I be notified if someone edits a check I own? + +Yes. You receive an **Ownership** in-app notification of the form *"{updater} updated a check you own"* whenever someone other than you saves a change. The notification links directly to the affected check. + +#### Do I get a notification when I edit my own check? + +No. Self-edits do not generate a notification. + +#### Why isn't the Qualytics user receiving notifications? + +The `Qualytics` user does not have a notification inbox. Updates on AI Managed checks owned by `Qualytics` are silent until ownership is transferred to a regular user. + +#### I just got an Ownership notification but the check is still owned by the same person. Why? + +The notification fires on save when the updater is not the owner. If someone other than the owner edits a non-ownership field (description, tags, status, and so on), the owner gets notified even though the owner did not change. + +## Filtering + +#### What is the difference between the Owned subtab and the Owner filter? + +The **Owned** subtab is a one-click shortcut to "checks I own": it sets the owner filter to your user automatically. The **Owner** filter in the filter panel lets you pick any user, including the `Qualytics` user, to scope the list to checks they own. + +#### Can I filter to checks owned by Qualytics? + +Yes. Open the **Owner** filter, find `Qualytics` at the top of the list (or use the search field), and select it. The list narrows to checks still owned by Qualytics (typically AI Managed checks that no one has taken over). + +#### Can I combine the Owned subtab with other filters? + +Yes. The **Owned** subtab is independent from the status (Active / Draft / Archived) parent tabs and from the filter panel. For example, **Active > Owned** plus a tag filter of `pii` narrows the list to your active checks tagged `pii`. + +## History + +#### Are ownership changes tracked? + +Yes. Every change to the owner is recorded in the check's **History** section, with the user who made the change, the timestamp, and the previous owner. Implicit transfers (from `Qualytics` to a regular user) and Drafter activation transfers appear in the same timeline. + +#### Is the original owner kept after a transfer? + +The original owner is preserved in the check's history but no longer on the check itself: the Owner field shows only the current owner. To find the previous owner, open the check's **History** and look for the ownership change entry. + +## API + +#### How do I set an explicit owner on `POST /quality-checks`? + +Include the `owner_id` field in the create payload, set to the target user's integer ID. See [API · Create a check with an explicit owner](api.md#create-a-check-with-an-explicit-owner){:target="_blank"}. + +#### How do I transfer ownership via the API? + +Send `PUT /quality-checks/{id}` with the check's `description` plus `owner_id` set to the new user's ID. For many checks at once, use `PATCH /quality-checks` with a list of `{ id, owner_id }` pairs. See [API · Transfer ownership across many checks](api.md#transfer-ownership-across-many-checks){:target="_blank"}. + +#### Is there an API equivalent of the Owned subtab? + +Yes. `GET /quality-checks/listing?owner=true&count_perspective=checks` returns checks owned by the user issuing the request, the same scope the UI uses. See [API · List checks owned by the current user](api.md#list-checks-owned-by-the-current-user){:target="_blank"}. diff --git a/docs/data-quality-checks/ownership/getting-started.md b/docs/data-quality-checks/ownership/getting-started.md new file mode 100644 index 0000000000..9041d48186 --- /dev/null +++ b/docs/data-quality-checks/ownership/getting-started.md @@ -0,0 +1,88 @@ +# :material-book-open-page-variant:{ .middle style="color: var(--q-brick)" } Getting Started with Quality Check Ownership + +Every quality check has an **owner**: a single user responsible for it. Ownership drives check filtering by responsibility, in-app notifications when someone edits a check you own, and the audit trail in the check's history. In this section you'll learn what ownership controls, the three transfer modes (explicit, implicit, and Drafter activation), how to change the owner from the UI and API, and how notifications, history, and filtering behave. + +![Ownership section in the Authored Check Details modal, showing the Owner and Anomaly assignee fields](../../assets/data-quality-checks/ownership/getting-started/ownership-section.png) + +!!! info "Permissions" + The **Author** team permission on the check's datastore is required to change a check's owner. Users selectable as the new owner need at least the **Drafter** permission on the same datastore. + +--- + +## Deep Dive + +
+ +- :material-book-open-variant:{ .lg .middle } **Introduction** + + --- + + Conceptual overview of the **Owner** field, why ownership matters, and the three transfer modes at a glance. + + [:octicons-arrow-right-24: Introduction](deep-dive/introduction.md) + +- :material-file-cog:{ .lg .middle } **How It Works** + + --- + + Full semantics: defaults at creation, the three transfer modes in detail, permissions, notifications, history tracking, and filtering. + + [:octicons-arrow-right-24: How It Works](deep-dive/how-it-works.md) + +- :material-text-box-edit-outline:{ .lg .middle } **Examples** + + --- + + Production scenarios that show ownership in action: onboarding, handoffs, notification-driven workflows, compliance audits, and Draft promotion. + + [:octicons-arrow-right-24: Examples](deep-dive/examples.md) + +
+ +--- + +## How-tos + +
+ +- :material-pencil-circle:{ .lg .middle } **Change Check Owner** + + --- + + Transfer ownership of a single check from the Edit Check form. + + [:octicons-arrow-right-24: Change Check Owner](how-tos/change-owner.md) + +- :material-dots-vertical-circle:{ .lg .middle } **Bulk Change Check Owner** + + --- + + Apply the same owner to many checks at once from the Bulk Edit Checks modal. + + [:octicons-arrow-right-24: Bulk Change Check Owner](how-tos/bulk-change-owner.md) + +
+ +--- + +## API & FAQ + +
+ +- :material-api:{ .lg .middle } **API** + + --- + + The `owner_id` field on create/update payloads, the `owner_id` and `owner` query parameters for filtering, and sample requests. + + [:octicons-arrow-right-24: API](api.md) + +- :material-help-circle-outline:{ .lg .middle } **FAQ** + + --- + + Short answers to frequent questions about ownership defaults, transfers, notifications, and filtering. + + [:octicons-arrow-right-24: FAQ](faq.md) + +
diff --git a/docs/data-quality-checks/ownership/how-tos/bulk-change-owner.md b/docs/data-quality-checks/ownership/how-tos/bulk-change-owner.md new file mode 100644 index 0000000000..a2a7d1f1ed --- /dev/null +++ b/docs/data-quality-checks/ownership/how-tos/bulk-change-owner.md @@ -0,0 +1,95 @@ +# Bulk Change Check Owner + +Use this flow when you want to apply the same owner to many quality checks at once. To change the owner on a single check from its Edit form, see [Change Check Owner](change-owner.md){:target="_blank"}. For how the field behaves in detail, see [How It Works](../deep-dive/how-it-works.md){:target="_blank"}. For programmatic access, see the [Ownership API](../api.md){:target="_blank"}. + +!!! info + Bulk-editing the owner requires the **Author** team permission (or higher) on the datastore of every selected check. The new owner must have at least the **Drafter** team permission on the same datastore. + +You can launch a bulk owner change from two places, and the flow is identical because both views use the same **Bulk Edit Checks** modal. Pick the tab that matches where you start from. + +=== "From a Datastore Checks tab" + + **Step 1:** Open the source datastore and go to the **Quality Checks** tab. You see the list of checks for that datastore. + + ![datastore-step-1-checks-list](../../../assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-1-checks-list.png) + + **Step 2:** Hover each check row and click the checkbox on the left to select it. The selected rows stay highlighted and a counter showing the count (for example, **2 selected**) appears at the top of the list. + + ![datastore-step-2-select-checks](../../../assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-2-select-checks.png) + + **Step 3:** Click the **Bulk menu :material-dots-vertical:{ style="color: var(--md-default-fg-color)" }** button next to the **N selected** counter. + + ![datastore-step-3-bulk-menu-icon](../../../assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-3-bulk-menu-icon.png) + + **Step 4:** A menu opens showing the bulk actions available: **Edit**, **Draft**, **Promote**, and **Archive**. + + ![datastore-step-4-menu-options](../../../assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-4-menu-options.png) + + **Step 5:** Click **Edit :material-square-edit-outline:{ style="color: var(--md-default-fg-color)" }**. + + ![datastore-step-5-edit-option](../../../assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-5-edit-option.png) + + **Step 6:** The **Bulk Edit Checks** modal opens with the editable fields (**Filter Clause**, **Tags**, **Additional Metadata**, **Owner**, **Anomaly Assignee**) listed with toggles set to off. A banner at the top warns that the action will **overwrite existing data** for the selected checks. + + ![datastore-step-6-bulk-modal](../../../assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-6-bulk-modal.png) + + **Step 7:** Toggle on the **Owner** row. + + ![datastore-step-7-toggle-owner](../../../assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-7-toggle-owner.png) + + **Step 8:** Click the dropdown and select the new owner from the list. It contains every user with at least the **Drafter** team permission on the datastore. + + ![datastore-step-8-user-list](../../../assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-8-user-list.png) + + **Step 9:** Click **Save** to apply the new owner to every selected check. + + ![datastore-step-9-save-button](../../../assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-9-save-button.png) + + **Step 10:** A success message appears at the top of the page, and the **Owner** column refreshes to show the new owner avatar on every selected row. Each check's **History** records the bulk change. + + ![datastore-step-10-success](../../../assets/data-quality-checks/ownership/how-tos/bulk-change-owner/datastore-step-10-success.png) + +=== "From a Check Template" + + **Step 1:** Open the source datastore, go to the **Check Templates** tab, and open the template that owns the checks. The template's **Checks** tab shows every check attached to it. + + ![template-step-1-template-checks](../../../assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-1-template-checks.png) + + **Step 2:** Hover each check row and click the checkbox on the left to select it. The selected rows stay highlighted and a counter showing the count (for example, **2 selected**) appears at the top of the list. + + ![template-step-2-select-checks](../../../assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-2-select-checks.png) + + **Step 3:** Click the **Bulk menu :material-dots-vertical:{ style="color: var(--md-default-fg-color)" }** button next to the **N selected** counter. + + ![template-step-3-bulk-menu-icon](../../../assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-3-bulk-menu-icon.png) + + **Step 4:** A menu opens showing the bulk actions available: **Edit**, **Draft**, **Promote**, and **Archive**. + + ![template-step-4-menu-options](../../../assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-4-menu-options.png) + + **Step 5:** Click **Edit :material-square-edit-outline:{ style="color: var(--md-default-fg-color)" }**. + + ![template-step-5-edit-option](../../../assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-5-edit-option.png) + + **Step 6:** The **Bulk Edit Checks** modal opens with the editable fields (**Filter Clause**, **Tags**, **Additional Metadata**, **Owner**, **Anomaly Assignee**) listed with toggles set to off. A banner at the top warns that the action will **overwrite existing data** for the selected checks. + + ![template-step-6-bulk-modal](../../../assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-6-bulk-modal.png) + + **Step 7:** Toggle on the **Owner** row. + + ![template-step-7-toggle-owner](../../../assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-7-toggle-owner.png) + + **Step 8:** Click the dropdown and select the new owner from the list. It contains every user with at least the **Drafter** team permission on the datastore. + + ![template-step-8-user-list](../../../assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-8-user-list.png) + + **Step 9:** Click **Save** to apply the new owner to every selected check. + + ![template-step-9-save-button](../../../assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-9-save-button.png) + + **Step 10:** A success message appears at the top of the page, and the **Owner** column refreshes to show the new owner avatar on every selected row. Each check's **History** records the bulk change. + + ![template-step-10-success](../../../assets/data-quality-checks/ownership/how-tos/bulk-change-owner/template-step-10-success.png) + +!!! warning "Bulk replaces, not merges" + The value you choose in the **Bulk Edit Checks** modal becomes the owner for every selected check. There is no merge step: if some of the selected checks were previously owned by other users, those owners are replaced. diff --git a/docs/data-quality-checks/ownership/how-tos/change-owner.md b/docs/data-quality-checks/ownership/how-tos/change-owner.md new file mode 100644 index 0000000000..08f80b090d --- /dev/null +++ b/docs/data-quality-checks/ownership/how-tos/change-owner.md @@ -0,0 +1,85 @@ +# Change Check Owner + +Step-by-step tutorial for transferring the **Owner** of a single quality check to another user. To apply the same owner to many checks at once, see [Bulk Change Check Owner](bulk-change-owner.md){:target="_blank"}. For how the field behaves in detail, see [How It Works](../deep-dive/how-it-works.md){:target="_blank"}. For programmatic access, see the [Ownership API](../api.md){:target="_blank"}. + +You can change the owner from two places. The flow is identical once the **Check Details** modal opens, so pick the tab that matches where you start from. + +=== "From a Datastore Checks tab" + + **Step 1:** Open the source datastore, go to the **Quality Checks** tab, and open the check whose owner you want to change. On the check detail page, click the **Options :material-cog:{ style="color: var(--md-default-fg-color)" }** button in the top-right corner. + + ![datastore-step-1-options-icon](../../../assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-1-options-icon.png) + + **Step 2:** The options menu opens. + + ![datastore-step-2-options-menu](../../../assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-2-options-menu.png) + + **Step 3:** Click **Edit :material-pencil-outline:{ style="color: var(--md-default-fg-color)" }**. + + ![datastore-step-3-edit-option](../../../assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-3-edit-option.png) + + **Step 4:** The **Check Details** modal opens, showing the check's properties. Scroll until you reach the **Ownership** section. + + ![datastore-step-4-edit-modal](../../../assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-4-edit-modal.png) + + **Step 5:** Locate the **Owner** field. The current owner is shown as an avatar with the user's name. + + ![datastore-step-5-owner-field](../../../assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-5-owner-field.png) + + **Step 6:** Click the **Owner** dropdown. A user list opens with every user who has at least the **Drafter** team permission on the datastore. + + ![datastore-step-6-user-list](../../../assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-6-user-list.png) + + **Step 7:** Select the new owner from the list. The **Owner** field updates to show the chosen user. + + ![datastore-step-7-owner-selected](../../../assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-7-owner-selected.png) + + **Step 8:** Click **Update** at the bottom of the modal to save the change. + + ![datastore-step-8-update-button](../../../assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-8-update-button.png) + + **Step 9:** A success message appears at the top of the page, and the check's **Summary** shows the new owner avatar. The change is recorded in the **History** section. + + ![datastore-step-9-success](../../../assets/data-quality-checks/ownership/how-tos/change-owner/datastore-step-9-success.png) + +=== "From Explore > Checks" + + !!! note "Check Template entry point" + The same procedure shown in this tab also applies when opening a check from a **Check Template** (Library > **Check Templates** > select the template > **Checks** tab). Clicking the check row opens the **Check Details** modal directly. + + **Step 1:** Open **Explore > Checks**. The list of checks across all datastores appears. + + ![explore-step-1-checks-list](../../../assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-1-checks-list.png) + + **Step 2:** Click the row of the check whose owner you want to change. + + ![explore-step-2-select-check](../../../assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-2-select-check.png) + + **Step 3:** The **Check Details** modal opens, showing the check's properties. Scroll until you reach the **Ownership** section. + + ![explore-step-3-edit-modal](../../../assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-3-edit-modal.png) + + **Step 4:** Locate the **Owner** field. The current owner is shown as an avatar with the user's name. + + ![explore-step-4-owner-field](../../../assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-4-owner-field.png) + + **Step 5:** Click the **Owner** dropdown. A user list opens, showing every user with at least the **Drafter** team permission on the datastore. + + ![explore-step-5-user-list](../../../assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-5-user-list.png) + + **Step 6:** Select the new owner from the list. The **Owner** field updates to show the chosen user. + + ![explore-step-6-owner-selected](../../../assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-6-owner-selected.png) + + **Step 7:** Click **Update** at the bottom of the modal to save the change. + + ![explore-step-7-update-button](../../../assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-7-update-button.png) + + **Step 8:** A success message appears at the top of the page, and the check's row in the list shows the new owner avatar. The change is recorded in the **History** section. + + ![explore-step-8-success](../../../assets/data-quality-checks/ownership/how-tos/change-owner/explore-step-8-success.png) + +!!! info + Changing the owner requires the **Author** team permission (or higher) on the check's datastore. The new owner must have at least the **Drafter** team permission on the same datastore. + + When the check is an [AI Managed check](../deep-dive/how-it-works.md#defaults-at-creation-time){:target="_blank"} still owned by `Qualytics`, the `Qualytics` user is pinned at the top of the **Owner** dropdown. Once the owner is transferred away from `Qualytics`, the dropdown disables `Qualytics` as a selectable owner; the inline warning **"Once transferred, ownership cannot be returned to Qualytics"** makes this explicit. The new owner receives an **Ownership** in-app notification the next time someone else updates the check; see [How It Works · Notifications](../deep-dive/how-it-works.md#notifications){:target="_blank"}. diff --git a/mkdocs.yml b/mkdocs.yml index e54bcd4a70..30c40dd720 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -289,6 +289,17 @@ nav: - Data Quality Checks: - Overview: data-quality-checks/overview-of-a-check.md - Authored: data-quality-checks/authored-check.md + - Ownership: + - Getting Started: data-quality-checks/ownership/getting-started.md + - Deep Dive: + - Introduction: data-quality-checks/ownership/deep-dive/introduction.md + - How It Works: data-quality-checks/ownership/deep-dive/how-it-works.md + - Examples: data-quality-checks/ownership/deep-dive/examples.md + - How-tos: + - Change Owner: data-quality-checks/ownership/how-tos/change-owner.md + - Bulk Change Owner: data-quality-checks/ownership/how-tos/bulk-change-owner.md + - API: data-quality-checks/ownership/api.md + - FAQ: data-quality-checks/ownership/faq.md - AI Managed: - Getting Started: data-quality-checks/ai-managed/getting-started.md - Deep Dive: