diff --git a/.aida/change_domains.yaml b/.aida/change_domains.yaml new file mode 100644 index 000000000..76bcb6967 --- /dev/null +++ b/.aida/change_domains.yaml @@ -0,0 +1,43 @@ +# (C) 2026 GoodData Corporation +# AIDA change domain classification +# +# Define how changed paths map to validation domains. +# See `.aida/validation_policy.yaml` for mapping domains to pipelines. +domains: + - id: python-package + description: Any workspace Python package under packages/* + match_globs: + - "packages/*/src/**/*.py" + - "packages/*/tests/**/*.py" + - "packages/*/pyproject.toml" + - "packages/*/tox.ini" + - "packages/*/Makefile" + root_depth: 2 + + - id: api-client + description: Generated API client package and its local config + match_globs: + - "gooddata-api-client/**/*.py" + - "gooddata-api-client/requirements.txt" + - "gooddata-api-client/test-requirements.txt" + - "gooddata-api-client/setup.py" + - "gooddata-api-client/tox.ini" + root_depth: 1 + + - id: repo-tooling + description: Root-level shared tooling and workspace configuration + match_globs: + - "pyproject.toml" + - "Makefile" + - "project_common.mk" + - "ci_tests.mk" + root_depth: 0 + + - id: aida-config + description: AIDA workflow configuration and local MCP wiring + match_globs: + - ".aida/**/*.yaml" + - ".aida/**/*.mdc" + - ".mcp.json" + - ".claude/CLAUDE.md" + root_depth: 0 diff --git a/.aida/git_policy.yaml b/.aida/git_policy.yaml new file mode 100644 index 000000000..3e6073b27 --- /dev/null +++ b/.aida/git_policy.yaml @@ -0,0 +1,21 @@ +# (C) 2026 GoodData Corporation +# AIDA git policy +# +# Configure commit and git workflow policy used by AIDA tools. +git_policy: + commit: + # Max allowed characters for the full commit subject line. + subject_max_chars: 70 + # Allowed values for required `risk:` footer. + risk_values: [nonprod, low, high] + # Require AI contribution metadata (`AI-Code-Share`) in each commit. + require_ai_share: false + # Require `Co-authored-by:` footer in each commit. + require_co_authored_by: false + # Allow `--ai-share-auto ` (deterministic actor=100). + enable_ai_share_auto: true + workflow: + # Prefer `git push --force-with-lease` over `--force` for unpublished branches. + prefer_force_with_lease: true + # Allow autosquash/rebase only for unpublished (not yet shared) commits. + autosquash_unpublished_only: true diff --git a/.aida/rules/packages/gooddata-dbt.mdc b/.aida/rules/packages/gooddata-dbt.mdc new file mode 100644 index 000000000..12113cef4 --- /dev/null +++ b/.aida/rules/packages/gooddata-dbt.mdc @@ -0,0 +1,38 @@ +# (C) 2026 GoodData Corporation +--- +description: GoodData dbt package - bridge from dbt metadata to GoodData semantic model +alwaysApply: false +--- + +# GoodData dbt Package + +**Location**: `packages/gooddata-dbt/` + +## Owns + +- CLI workflow for dbt-oriented GoodData operations (`gooddata-dbt`) +- Conversion of dbt models/profiles into GoodData LDM and analytics deployment inputs +- Workspace and data source provisioning helpers driven by `gooddata.yaml` + +## Does NOT Own + +- Core GoodData SDK domain/client services → `gooddata-sdk` +- Generic orchestration or storage automation → `gooddata-pipelines` +- dbt runtime implementation itself (provided by dbt tooling) + +## Architecture + +**Entry point**: `gooddata_dbt.main:main` + +**Primary package**: `src/gooddata_dbt` + +**Depends on**: `gooddata-sdk` + +## Testing + +Use package-local pytest suites under `packages/gooddata-dbt/tests`. + +## Dependencies + +Required: technologies/python, packages/gooddata-sdk +Related: technologies/testing, packages/gooddata-pipelines diff --git a/.aida/rules/packages/gooddata-fdw.mdc b/.aida/rules/packages/gooddata-fdw.mdc new file mode 100644 index 000000000..f27a98bb4 --- /dev/null +++ b/.aida/rules/packages/gooddata-fdw.mdc @@ -0,0 +1,38 @@ +# (C) 2026 GoodData Corporation +--- +description: GoodData FDW package - PostgreSQL foreign data wrapper integration +alwaysApply: false +--- + +# GoodData FDW Package + +**Location**: `packages/gooddata-fdw/` + +## Owns + +- PostgreSQL FDW integration for exposing GoodData data as SQL-accessible foreign tables +- Translation layer between FDW execution flow and GoodData SDK calls +- Import/execute FDW command behavior used by package tests and docs + +## Does NOT Own + +- Core API/service client behavior → `gooddata-sdk` +- Flight RPC server infrastructure → `gooddata-flight-server` +- FlexConnect function runtime → `gooddata-flexconnect` + +## Architecture + +**Primary package**: `src/gooddata_fdw` + +**Runtime dependency**: multicorn/PostgreSQL FDW environment + +**Depends on**: `gooddata-sdk` + +## Testing + +Use package-local pytest suites under `packages/gooddata-fdw/tests`. + +## Dependencies + +Required: technologies/python, packages/gooddata-sdk +Related: technologies/testing diff --git a/.aida/rules/packages/gooddata-flexconnect.mdc b/.aida/rules/packages/gooddata-flexconnect.mdc new file mode 100644 index 000000000..cf23c79cd --- /dev/null +++ b/.aida/rules/packages/gooddata-flexconnect.mdc @@ -0,0 +1,38 @@ +# (C) 2026 GoodData Corporation +--- +description: GoodData FlexConnect package - custom data source framework for GoodData +alwaysApply: false +--- + +# GoodData FlexConnect Package + +**Location**: `packages/gooddata-flexconnect/` + +## Owns + +- FlexConnect framework for authoring custom table-function style data sources +- Runtime contract for mapping custom function outputs into GoodData datasets +- Integration layer combining GoodData SDK interactions with Flight server hosting + +## Does NOT Own + +- Generic Flight server infrastructure and CLI → `gooddata-flight-server` +- Core GoodData Cloud domain/catalog/compute APIs → `gooddata-sdk` +- PostgreSQL FDW integration → `gooddata-fdw` + +## Architecture + +**Primary package**: `src/gooddata_flexconnect` + +**Depends on**: `gooddata-flight-server`, `gooddata-sdk` + +**Typical usage**: external FlexConnect projects consume this package as a framework dependency + +## Testing + +Use package-local pytest suites under `packages/gooddata-flexconnect/tests`. + +## Dependencies + +Required: technologies/python, packages/gooddata-flight-server, packages/gooddata-sdk +Related: technologies/testing diff --git a/.aida/rules/packages/gooddata-flight-server.mdc b/.aida/rules/packages/gooddata-flight-server.mdc new file mode 100644 index 000000000..eeb50c058 --- /dev/null +++ b/.aida/rules/packages/gooddata-flight-server.mdc @@ -0,0 +1,38 @@ +# (C) 2026 GoodData Corporation +--- +description: GoodData Flight Server package - pluggable Flight RPC server foundation +alwaysApply: false +--- + +# GoodData Flight Server Package + +**Location**: `packages/gooddata-flight-server/` + +## Owns + +- Reusable Flight RPC server runtime and CLI (`gooddata-flight-server`) +- Server bootstrap, lifecycle handling, observability, and auth/token integration +- Configuration patterns for running custom Flight method providers + +## Does NOT Own + +- Core GoodData Cloud domain/catalog/compute SDK APIs → `gooddata-sdk` +- Product-specific data source functions and semantic model mapping → `gooddata-flexconnect` +- Lifecycle provisioning and backup workflows → `gooddata-pipelines` + +## Architecture + +**Entry point**: `gooddata_flight_server.cli:server_cli` + +**Primary package**: `src/gooddata_flight_server` + +**Key stack**: `pyarrow.flight`, `dynaconf`, telemetry/metrics integrations + +## Testing + +Use package-local pytest suites under `packages/gooddata-flight-server/tests`. + +## Dependencies + +Required: technologies/python +Related: technologies/testing, packages/gooddata-flexconnect diff --git a/.cursor/rules/packages/gooddata-pandas.mdc b/.aida/rules/packages/gooddata-pandas.mdc similarity index 96% rename from .cursor/rules/packages/gooddata-pandas.mdc rename to .aida/rules/packages/gooddata-pandas.mdc index be4aa3bfd..0637e9914 100644 --- a/.cursor/rules/packages/gooddata-pandas.mdc +++ b/.aida/rules/packages/gooddata-pandas.mdc @@ -1,4 +1,4 @@ -# (C) 2025 GoodData Corporation +# (C) 2026 GoodData Corporation --- description: GoodData Pandas package - pandas integration layer for GoodData SDK alwaysApply: false diff --git a/.aida/rules/packages/gooddata-pipelines.mdc b/.aida/rules/packages/gooddata-pipelines.mdc new file mode 100644 index 000000000..2fae815fd --- /dev/null +++ b/.aida/rules/packages/gooddata-pipelines.mdc @@ -0,0 +1,38 @@ +# (C) 2026 GoodData Corporation +--- +description: GoodData Pipelines package - lifecycle automation for GoodData Cloud +alwaysApply: false +--- + +# GoodData Pipelines Package + +**Location**: `packages/gooddata-pipelines/` + +## Owns + +- High-level automation flows for provisioning users, groups, permissions, and workspace hierarchies +- Backup and restore workflows for workspace metadata (local, S3, Azure Blob targets) +- LDM extension workflows for child workspaces + +## Does NOT Own + +- Core platform API/service abstractions and low-level client behavior → `gooddata-sdk` +- dbt metadata conversion and deployment CLI → `gooddata-dbt` +- Flight RPC runtime infrastructure → `gooddata-flight-server` + +## Architecture + +**Primary package**: `src/gooddata_pipelines` + +**Depends on**: `gooddata-sdk` plus cloud storage SDK integrations + +**Primary modules**: `provisioning`, `backup_and_restore`, `ldm_extension` + +## Testing + +Use package-local pytest suites under `packages/gooddata-pipelines/tests`. + +## Dependencies + +Required: technologies/python, packages/gooddata-sdk +Related: technologies/testing diff --git a/.cursor/rules/packages/gooddata-sdk.mdc b/.aida/rules/packages/gooddata-sdk.mdc similarity index 81% rename from .cursor/rules/packages/gooddata-sdk.mdc rename to .aida/rules/packages/gooddata-sdk.mdc index cc0b065f6..f1b4f5045 100644 --- a/.cursor/rules/packages/gooddata-sdk.mdc +++ b/.aida/rules/packages/gooddata-sdk.mdc @@ -1,4 +1,4 @@ -# (C) 2025 GoodData Corporation +# (C) 2026 GoodData Corporation --- description: GoodData SDK core package - primary interface for GoodData Cloud alwaysApply: false @@ -22,6 +22,9 @@ alwaysApply: false - Pandas integration → gooddata-pandas package - dbt integration → gooddata-dbt package - Flight server → gooddata-flight-server package +- FlexConnect data source framework → gooddata-flexconnect package +- Lifecycle automation workflows → gooddata-pipelines package +- PostgreSQL FDW integration → gooddata-fdw package - API client generation → gooddata-api-client (generated) ## Architecture @@ -48,4 +51,4 @@ Uses vcrpy cassettes. See `technologies/testing` rule for workflow. ## Dependencies Required: technologies/python, technologies/testing -Related: packages/gooddata-pandas +Related: packages/gooddata-pandas, packages/gooddata-dbt, packages/gooddata-pipelines diff --git a/.aida/rules/packages/tests-support.mdc b/.aida/rules/packages/tests-support.mdc new file mode 100644 index 000000000..ab3acd697 --- /dev/null +++ b/.aida/rules/packages/tests-support.mdc @@ -0,0 +1,38 @@ +# (C) 2026 GoodData Corporation +--- +description: Tests support package - shared test helpers for SDK repository packages +alwaysApply: false +--- + +# Tests Support Package + +**Location**: `packages/tests-support/` + +## Owns + +- Shared test utilities reused across multiple repository packages +- VCR helpers for cassette normalization and deterministic request/response handling +- File and deep-comparison helper functions used by package test suites + +## Does NOT Own + +- Product/runtime code for any customer-facing package +- Package-specific test scenarios (those remain with each package under `packages/*/tests`) +- Core SDK API behavior and domain services → `gooddata-sdk` + +## Architecture + +**Primary package**: `src/tests_support` + +**Main modules**: `vcrpy_utils.py`, `compare_utils.py`, `file_utils.py` + +**Role**: test-only utility package consumed from dependency groups in other packages + +## Testing + +Prefer adding shared test helpers here only when at least two packages need the behavior. + +## Dependencies + +Required: technologies/python +Related: technologies/testing, packages/gooddata-sdk, packages/gooddata-pandas diff --git a/.aida/validation_policy.yaml b/.aida/validation_policy.yaml new file mode 100644 index 000000000..acc3feab1 --- /dev/null +++ b/.aida/validation_policy.yaml @@ -0,0 +1,71 @@ +# (C) 2026 GoodData Corporation +# AIDA validation policy +# +# This file wires domains -> pipelines -> steps (command_id + processor_id). +# Initially empty (validate may no-op until you configure routes). +validation_policy: + codegen: + - id: api-client-regeneration-check + match_globs: + - "schemas/**/*.json" + - ".openapi-generator/**/*.yaml" + - "scripts/generate_client.sh" + pipeline: api-client-fast + scopes: ["pre_push"] + + routes: + - domain: python-package + pipeline: package-fast + - domain: api-client + pipeline: api-client-fast + - domain: repo-tooling + pipeline: repo-fast + - domain: aida-config + pipeline: aida-config + + pipelines: + package-fast: + steps: + - command_id: package-lint + processor_id: passthrough + - command_id: package-type-check + processor_id: passthrough + - command_id: package-test-py314 + processor_id: pytest + + package-compat: + steps: + - command_id: package-lint + processor_id: passthrough + - command_id: package-type-check + processor_id: passthrough + - command_id: package-test-py314 + processor_id: pytest + - command_id: package-test-py310 + processor_id: pytest + + package-full: + steps: + - command_id: package-lint + processor_id: passthrough + - command_id: package-type-check + processor_id: passthrough + - command_id: package-test-matrix + processor_id: pytest + + api-client-fast: + steps: + - command_id: api-client-tests + processor_id: pytest + + repo-fast: + steps: + - command_id: workspace-lint + processor_id: passthrough + - command_id: workspace-type-check + processor_id: passthrough + + aida-config: + steps: + - command_id: aida-doctor + processor_id: passthrough diff --git a/.aida/validation_registry.yaml b/.aida/validation_registry.yaml new file mode 100644 index 000000000..6a5005a5e --- /dev/null +++ b/.aida/validation_registry.yaml @@ -0,0 +1,50 @@ +# (C) 2026 GoodData Corporation +# AIDA validation registry +# +# Define command_id and processor_id specifications referenced by validation_policy.yaml. +registry: + includes: [] + commands: + package-lint: + argv: ["make", "-C", "{root}", "lint"] + cwd: "{workspace_root}" + package-type-check: + argv: ["make", "-C", "{root}", "type-check"] + cwd: "{workspace_root}" + package-test: + argv: ["make", "-C", "{root}", "test"] + cwd: "{workspace_root}" + package-test-py314: + argv: ["make", "-C", "{root}", "test"] + cwd: "{workspace_root}" + env: + TEST_ENVS: py314 + package-test-py310: + argv: ["make", "-C", "{root}", "test"] + cwd: "{workspace_root}" + env: + TEST_ENVS: py310 + package-test-matrix: + argv: ["make", "-C", "{root}", "test"] + cwd: "{workspace_root}" + env: + TEST_ENVS: py314,py313,py312,py311,py310 + workspace-lint: + argv: ["make", "lint"] + cwd: "{workspace_root}" + workspace-type-check: + argv: ["make", "type-check"] + cwd: "{workspace_root}" + api-client-tests: + argv: ["uv", "run", "tox", "-c", "{workspace_root}/gooddata-api-client/tox.ini"] + cwd: "{workspace_root}/gooddata-api-client" + aida-doctor: + argv: ["aida-mcp", "doctor"] + cwd: "{workspace_root}" + processors: + passthrough: + kind: builtin + builtin_id: passthrough + pytest: + kind: builtin + builtin_id: pytest diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md new file mode 100644 index 000000000..654a14f46 --- /dev/null +++ b/.claude/CLAUDE.md @@ -0,0 +1,57 @@ +--- +apply: always +--- + +# AIDA Development Workflow + +This file contains only: +- the mandatory workflow, and +- which MCP tools to use in each phase. + +Do not duplicate detailed “how to” guidance here. Always rely on MCP tool descriptions and `get_rules(...)`. + +## Editing this file (template-driven) + +This file is generated by `aida-mcp init` from templates shipped in the `aida-mcp` package. + +- **Do not hand-edit** `.cursor/rules/aida.mdc` or `.claude/CLAUDE.md` in a repo. +- To change the content, **update the templates in the `aida-mcp` package** and then rerun `aida-mcp init` in the repo. + +## Post-init check + +- After `aida-mcp init`, if MCP tools like `get_rules` or `validate` are missing, run `aida-mcp doctor`. + +## Workflow (mandatory) + +### 1) Get rules + +- At the start of every task (and again on scope change), call `get_rules(query="...")`. +- Follow the rules returned by `get_rules` for the task. + +### 2) Implement + +- Make the requested change(s) following repository rules returned by `get_rules`. + +### 3) Validate (blocking) + +- If you changed code, you must validate before responding about code changes. +- Prefer the narrowest validation that is still correct (use `test_filter` when appropriate). +- Use the MCP validation tool `validate` (prefer this over raw `./gradlew` / `make`). +- If you changed `.proto` files, do not run proto regeneration manually; `validate` will run it when needed. +- If unsure what validation to run, call `get_rules(query="validation workflow")` and follow the returned guidance. + +### 4) Commit / PR (if asked) + +- Ask for the JIRA ticket if unknown. +- Before committing or creating a PR, call `get_rules(query="git")` and follow the returned guidance. +- For commit creation, use `aida-mcp commit` (do not use raw `git commit`). + +## When to create/update rules + +If any of these happen, propose updates to repo rules/config by following `get_rules(query="rules authoring")`: +- repeated friction (“how do I … in this repo?” keeps coming up) +- user dissatisfaction (“wrong”, “not what I meant”, “stop doing that”) +- recurring validation failures of the same kind +- large/risky cross-cutting changes + +Before creating/updating files under `.aida/` (including `.aida/rules/**` and `.aida/*.yaml`), ask the user for explicit permission and proceed only after approval. diff --git a/.cursor/rules/cursor/rules.mdc b/.cursor/rules/cursor/rules.mdc deleted file mode 100644 index c098ee831..000000000 --- a/.cursor/rules/cursor/rules.mdc +++ /dev/null @@ -1,86 +0,0 @@ -# (C) 2025 GoodData Corporation ---- -description: How to create or update Cursor rule files - includes minimal templates and standards -alwaysApply: false ---- - -# Creating and Updating Cursor Rules - -## Folder Structure - -- `.cursor/rules/general/` - General rules (always applied) -- `.cursor/rules/packages/` - Package-specific rules -- `.cursor/rules/technologies/` - Technology rules (Python, testing) -- `.cursor/rules/guides/shared/` - Shared conventions (commits, etc.) -- `.cursor/rules/cursor/` - Cursor workflow and meta-rules - -## Rule Creation Process - -1. **Ask for clarification** if codebase location is unclear -2. **Investigate the codebase** relevant to the rule -3. **Look at similar existing rules** as examples (better than templates) -4. **Keep it minimal** - target 25-40 lines max -5. **Focus on proprietary knowledge** - not generic patterns -6. **Remove anything that doesn't help Cursor** - do not put anything that doesn't help Cursor into any rule file - -## Updating Existing Rules - -**CRITICAL**: When asked to extend rules, be MINIMAL. Add only what prevents actual errors. - -**DO (Minimal):** -```python -# Just the pattern that fixes the error -from typing import TYPE_CHECKING, Any -if TYPE_CHECKING: - Context = MCPContext[Any, Any, Any] -``` - -**DON'T (Verbose):** -- ❌ Pattern explanations (why it works, alternatives, trade-offs) -- ❌ Multiple examples (good vs bad, before vs after) -- ❌ Best practices unrelated to errors -- ❌ Prose explanations ("Why:", "Note:", paragraphs) -- ❌ Decision matrices or tables (unless critical for error prevention) -- ❌ Checklists (unless they prevent actual errors) -- ❌ Step-by-step tutorials -- ❌ Verbose "correct vs wrong" comparisons - -**Rule of thumb**: If it didn't cause a validation error, don't add it to the rule. - -**Target length**: 25-40 lines. If over 50 lines, you're being too verbose. - -## Rule Structure (All Types) - -**Essential sections:** -- Description header (1 line) -- Owns / Does NOT Own (clear boundaries) -- Critical constraints or anti-patterns (if any) -- Dependencies (required rules to load together) - -**Optional sections:** -- Integration (only if complex) -- Proprietary patterns (only if non-obvious) -- Essential commands (only if unique to this package) - -## Quality Criteria - -**Good rule (25-40 lines):** -- ✅ Only proprietary/non-obvious knowledge -- ✅ Clear package boundaries -- ✅ Points to READMEs for details -- ✅ Copy-paste ready patterns (minimal examples) - -**Bad rule (>50 lines):** -- ❌ Generic technology descriptions -- ❌ Long explanations or tutorials -- ❌ Verbose examples with commentary -- ❌ Information already in code/docs - -## Rule Header Format - -```markdown ---- -description: {Brief but complete - used by Cursor for rule selection} -alwaysApply: false # (or true only for general rules) ---- -``` diff --git a/.cursor/rules/cursor/workflow-validation.mdc b/.cursor/rules/cursor/workflow-validation.mdc deleted file mode 100644 index 58ddb5e4e..000000000 --- a/.cursor/rules/cursor/workflow-validation.mdc +++ /dev/null @@ -1,26 +0,0 @@ -# (C) 2025 GoodData Corporation ---- -description: Cursor IDE workflow validation and rule management -alwaysApply: true ---- - -# Cursor IDE Workflow Validation - -## Workflow and output constraints - -- Include all rules related to the user question; if rules mention dependencies, include those too. -- After fully answering, report the list of used rules. -- Example: **Used rules**: general/general, technologies/python, packages/gooddata-sdk -- Do not print rule previews or long plans. -- Keep status updates to one short sentence. -- Never inline full rule contents; reference by rule path only when needed. -- Only list rule IDs in "Used rules:". - -## Rule Search Requirements - -Always look for relevant cursor rules in this repository based on the character of the changes. -Do not inline rule contents; reference rules by path only when necessary. - -## Git Commit Requirements - -Follow commit message format from `guides/shared/commits.mdc`. diff --git a/.cursor/rules/general/general.mdc b/.cursor/rules/general/general.mdc deleted file mode 100644 index 82be7e8a3..000000000 --- a/.cursor/rules/general/general.mdc +++ /dev/null @@ -1,85 +0,0 @@ -# (C) 2025 GoodData Corporation ---- -alwaysApply: true ---- - -# GoodData Python SDK Coding Guidelines - -Applies to all packages and code in this Python SDK workspace. -Think in steps before changes. Always search for relevant cursor rules based on the character of changes. - -## Core Principles - -**Search first, don't invent**: Always search this repository for everything related to the developer question. **Do not invent a new design for something that already exists!** - -**Code Principles**: **1** Simplicity, **2** Readability, **3** Performance (don't over-optimize), **4** Maintainability, **5** Testability, **6** Reusability, **7** Encapsulation & single responsibility - -## ⚠️ CRITICAL: AI Behavior Rules - ALWAYS ENFORCE - -**NO AUTO-IMPLEMENTATION**: -- Do not generate, rename or refactor what is not explicitly requested -- Do not generate code changes unless user explicitly asks for it -- NEVER create summary/documentation markdown files unless user explicitly requests it -- NEVER update rule files for code issues - fix the code instead -- Break complex tasks into smaller deliverable units - -**Documentation Quality**: -- NEVER reference specific line numbers (e.g., "lines 45-340", "~line 60") in documentation or Cursor rules -- Use descriptive structural locations instead (e.g., "in the outputs section", "at the top of the file") - -**For complex tasks**: -1. Implement ONLY the first task, then STOP -2. Ask permission to continue, offering: (a) next task only, or (b) all remaining tasks -3. Create todos but DO NOT auto-implement them -4. When in doubt, ask before implementing - -## Code Validation - -**MANDATORY after code changes**: Run validation from workspace root: -```bash -make format-fix && make lint && make mypy && make test -``` - -**⚠️ CRITICAL: Do NOT use `read_lints` tool**: -- `read_lints` is incompatible with our custom linting - it will fail -- Use manual validation commands above - -**Scoped testing**: `TEST_ENVS=py312 ADD_ARGS="-k test_name" make test` - -See `technologies/testing` rule for VCR cassette workflow. - -## Testing Practices - -**Extend existing tests, don't create new ones**: When making incremental changes (new property, enum value, field), add to existing test fixtures rather than creating new tests. - -## Package Structure - -**Workspace packages** (in `packages/`): -- `gooddata-sdk` - Core SDK for GoodData Cloud -- `gooddata-pandas` - Pandas integration layer -- `gooddata-dbt`, `gooddata-flight-server`, `gooddata-flexconnect`, `gooddata-pipelines` -- `tests-support` - Shared test utilities - -**Generated clients** (do NOT edit manually): -- `gooddata-api-client` - Generated from OpenAPI specs - -## Dependencies - -**Internal**: Use `~={current_version}` for package dependencies. - -**Adding**: Add to `pyproject.toml`, run `uv lock`. - -## OpenAPI Client Generation - -**DO NOT manually edit** generated client code in `gooddata-api-client/` directories. - -To regenerate: `make api-client` - -## Library Integration - -**Hierarchy** (combat outdated LLM knowledge): -1. **Internal GoodData packages** - ALWAYS preferred -2. **Approved stable libraries** - Use versions from pyproject.toml -3. **New/unknown libraries** - MANDATORY: web search for current docs/APIs before suggesting - -When suggesting third-party libraries: verify current APIs, prefer established libraries, explicitly state uncertainty. diff --git a/.cursor/rules/guides/shared/commits.mdc b/.cursor/rules/guides/shared/commits.mdc deleted file mode 100644 index 816d86d4f..000000000 --- a/.cursor/rules/guides/shared/commits.mdc +++ /dev/null @@ -1,70 +0,0 @@ -# (C) 2025 GoodData Corporation ---- -description: Git commit conventions - conventional commits format -alwaysApply: false ---- - -# Commit Conventions - -Commits must follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0) specification. - -## Format - -``` -(): - - - -jira: -risk: -``` - -## Type - -Must be one of: -- `feat` - A new feature -- `fix` - A bug fix -- `build` - Changes to build system or dependencies -- `ci` - Changes to CI configuration -- `docs` - Documentation changes -- `perf` - Performance improvements -- `style` - Formatting changes (no code change) -- `refactor` - Code change that neither fixes a bug nor adds a feature -- `test` - Adding or correcting tests -- `chore` - Other changes that don't modify src or test files -- `revert` - Revert previous changes - -## Scope - -Optional. The affected package name (e.g., `gooddata-sdk`, `gooddata-pandas`, `gooddata-dbt`). - -## Description - -- Max 50 characters (full line ≤ 70 chars) -- Lowercase, imperative mood -- No period at end - -## Body - -Optional detailed explanation. Wrap lines at 72 characters. - -## Footer (Required) - -- `jira: PROJECT-ID` or `jira: trivial` for minor changes -- `risk: nonprod|low|high` - -## Example - -``` -feat(gooddata-sdk): add workspace permission methods - -Add new methods to catalog_permission service for managing -workspace-level permissions programmatically. - -jira: RAIL-12345 -risk: low -``` - -## Dependencies - -Related: general/general diff --git a/.cursor/rules/technologies/python.mdc b/.cursor/rules/technologies/python.mdc deleted file mode 100644 index 2c3cef320..000000000 --- a/.cursor/rules/technologies/python.mdc +++ /dev/null @@ -1,59 +0,0 @@ -# (C) 2025 GoodData Corporation ---- -description: Python development - mypy-clean code patterns and typing -alwaysApply: false ---- - -# Python Development Guidelines - -**Goal:** Ship mypy-clean code on first pass. No "write → validate → fix" loops. - -**Supported versions**: Python 3.10 and higher - -## Imports - -**Use absolute imports only.** Relative imports break IDE navigation. -```python -from gooddata_sdk.client import GoodDataSdk # ✅ -from .client import GoodDataSdk # ❌ -``` - -**All imports must be at the top of the file.** Never import modules inside functions or in the middle of code. All `import` and `from ... import` statements must be placed at the top of the file, after the module docstring and `from __future__ import annotations` if present. - -## Type-first habits -- Every def + local (esp empty list/dict/set) annotated; dataclasses fully typed. -- Use `from __future__ import annotations` for forward references. -- Helpers when default mutable needed: - ```python - def _new_set() -> set[str]: - return set() - ``` - -## External data (YAML/JSON/etc.) -- Treat loader output as `Any`; guard then normalize keys: - ```python - raw = yaml.safe_load(handle) - if not isinstance(raw, dict): - raise ValueError("expected mapping") - cfg: dict[str, object] = {str(k): v for k, v in raw.items()} - ``` -- Narrow collections once: `entries = [x for x in cast(list[object], cfg.get("items", [])) if isinstance(x, str)]`. -- Prefer `TypedDict`/dataclass when schema known. - -## Logging & diagnostics -- Never log raw `Any`; cast or pre-format (`logger.warning("… %r", safe)`). -- Avoid redundant `isinstance` after data narrowed; mypy flags it. - -## Casts / guards -- Single authoritative `cast(...)` + reuse variable. -- Guard pattern: `if isinstance(mode_raw, str): mode = mode_raw else: raise ValueError("mode str")`. -- `typing.assert_never` for exhaustive branches. - -## Documentation - -**Google-style docstrings** for all public APIs. - -## Dependencies - -Required: general/general -Related: technologies/testing, packages/* diff --git a/.cursor/rules/technologies/testing.mdc b/.cursor/rules/technologies/testing.mdc deleted file mode 100644 index a13a625c3..000000000 --- a/.cursor/rules/technologies/testing.mdc +++ /dev/null @@ -1,58 +0,0 @@ -# (C) 2025 GoodData Corporation ---- -description: Validation and testing - VCR cassettes for HTTP snapshots -alwaysApply: false ---- - -# Validation & Testing - -## Validation Flow - -**From workspace root**: -```bash -make format-fix # ruff format + fix -make lint-fix # ruff lint + fix -make mypy # Type check (aliased as `make types`) -make test # pytest via tox (all Python versions) -``` - -**Scoped**: -```bash -TEST_ENVS=py312,py313 make test # Specific Python versions -ADD_ARGS="-k test_catalog" make test # Filter tests -RECREATE_ENVS=1 make test # Force tox rebuild -``` - -**CI-like**: `make test-ci` (Docker-based) - -## VCR Cassettes (HTTP Snapshots) - -**Purpose**: Record GoodData Cloud HTTP calls for reproducible tests. - -**Update workflow** (when API changes): -```bash -docker-compose up # Start local GoodData Cloud -make remove-cassettes # Delete old fixtures -make test # Generates new cassettes -git add tests/**/fixtures/*.yaml -``` - -**Location**: `tests/**/fixtures/*.yaml` - -## Test Pattern - -```python -@vcr.use_cassette("tests/catalog/fixtures/test_workspace.yaml") -def test_get_workspace(sdk): - workspace = sdk.catalog_workspace.get_workspace("demo") - assert workspace.id == "demo" -``` - -## Testing Practices - -**Extend existing tests, don't create new ones**: When making incremental changes (new property, enum value, field), add to existing test fixtures rather than creating new tests. If a test already validates round-trip, adding to the fixture is sufficient. - -## Dependencies - -Required: technologies/python -Related: general/general diff --git a/.cursor/rules/technologies/third-party-libraries.mdc b/.cursor/rules/technologies/third-party-libraries.mdc deleted file mode 100644 index fdb8122f9..000000000 --- a/.cursor/rules/technologies/third-party-libraries.mdc +++ /dev/null @@ -1,54 +0,0 @@ -# (C) 2025 GoodData Corporation ---- -description: Third-party library integration - preventing outdated LLM knowledge issues -alwaysApply: false ---- - -# Third-Party Library Integration - -## ⚠️ CRITICAL: Preventing Outdated Knowledge Issues - -**LLMs may have outdated training data. Always verify current information before suggesting third-party libraries.** - -## Library Integration Hierarchy - -### ✅ PREFERRED: Internal GoodData Packages -**ALWAYS use these instead of external alternatives:** -- `gooddata-sdk` - Core SDK functionality -- `gooddata-pandas` - Pandas integration -- `gooddata-api-client` - Generated API client - -### 🟡 APPROVED: Stable External Libraries -**Pre-approved (but verify versions in pyproject.toml):** -- pandas, numpy - Data processing -- attrs, cattrs - Data classes and serialization -- requests, httpx - HTTP clients -- pytest, vcrpy - Testing - -### 🔴 REQUIRES WEB SEARCH: Unknown/New Libraries -**MANDATORY verification before suggesting:** -- Any library not in approved lists above -- Libraries from rapidly changing ecosystems (AI/ML, async frameworks) -- Beta/alpha versions of any library -- Libraries with major version changes in last 6 months - -## When to ALWAYS Search the Web - -**MANDATORY TRIGGERS:** -1. New library integration (not in our approved stack) -2. Version-specific APIs (libraries known to change frequently) -3. Migration scenarios (upgrading between major versions) -4. Deprecated warnings -5. Fast-evolving ecosystems (Python AI/ML, async, type systems) -6. Cloud provider SDKs (AWS, GCP, Azure) - -**Search Strategy:** -- Search: "library-name current version documentation" -- Look for: "library-name migration guide" or "breaking changes" -- Check: Official GitHub repository for recent releases -- Verify: API examples from official docs (not generic tutorials) - -## Dependencies - -Required: technologies/python -Related: general/general diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 000000000..181a1f792 --- /dev/null +++ b/.mcp.json @@ -0,0 +1,11 @@ +{ + "mcpServers": { + "aida": { + "command": "aida-mcp", + "args": [], + "env": { + "AIDA_ENABLE_EMBEDDED_VENDOR_RULES": "true" + } + } + } +}