diff --git a/.cursor/rules/learn-technical.mdc b/.cursor/rules/learn-technical.mdc new file mode 100644 index 000000000..7172e4767 --- /dev/null +++ b/.cursor/rules/learn-technical.mdc @@ -0,0 +1,18 @@ +--- +description: Capture technical lessons learned into cursor rules +alwaysApply: true +--- + +# Technical Learnings + +When you discover a technical pattern, gotcha, or convention specific to this codebase, create or update a rule in `.cursor/rules/` to capture it. + +Examples of technical learnings worth capturing: + +- ORM differences between SQLAlchemy and Django models (field names, method names, enum types) +- Import conventions (canonical locations for shared enums, models, constants) +- Compatibility gotchas (e.g. `TextChoices` vs plain `Enum`, `cached_property` vs `property`) +- Test patterns (which factories to use, which fixtures, `@pytest.mark.django_db`) +- Architecture decisions (where shared code lives, what belongs in `libs/shared/` vs `apps/worker/`) + +Write the rule as a concise reference — something a developer (or agent) can consult mid-task. Include concrete examples where possible. diff --git a/.cursor/rules/learn-workflow.mdc b/.cursor/rules/learn-workflow.mdc new file mode 100644 index 000000000..b303a1ad3 --- /dev/null +++ b/.cursor/rules/learn-workflow.mdc @@ -0,0 +1,17 @@ +--- +description: Capture workflow lessons learned into cursor rules +alwaysApply: true +--- + +# Workflow Learnings + +When you discover a workflow pattern that should be repeated — or a mistake that should be avoided — create or update a rule in `.cursor/rules/` to capture it. + +Examples of workflow learnings worth capturing: + +- A git workflow that worked well (e.g. how to structure stacked PRs) +- A step that was missed and caused rework (e.g. forgetting to run linters) +- A review or PR convention the team expects +- A process for splitting, sequencing, or batching changes + +Write the rule as a concise, actionable instruction — not a story of what happened. Future agents should be able to follow it without context. diff --git a/.cursor/rules/pre-commit-checks.mdc b/.cursor/rules/pre-commit-checks.mdc new file mode 100644 index 000000000..63b9626ec --- /dev/null +++ b/.cursor/rules/pre-commit-checks.mdc @@ -0,0 +1,17 @@ +--- +description: Run pre-commit checks (ruff lint + format) before creating PRs or commits +alwaysApply: true +--- + +# Pre-commit Checks + +Before creating a PR or making a commit, always run the project's pre-commit hooks to catch lint and formatting issues: + +```bash +ruff check --fix . +ruff format . +``` + +If either command produces changes, stage the fixes and include them in the commit. + +This project uses `ruff` for both linting (`ruff check`) and formatting (`ruff format`), configured in `pyproject.toml` and enforced via `.pre-commit-config.yaml`. diff --git a/.cursor/rules/small-prs.mdc b/.cursor/rules/small-prs.mdc new file mode 100644 index 000000000..cae1ae0a5 --- /dev/null +++ b/.cursor/rules/small-prs.mdc @@ -0,0 +1,27 @@ +--- +description: Break large changes into small, focused PRs +alwaysApply: true +--- + +# Small, Focused PRs + +When a task involves multiple logical changes, split them into separate PRs rather than one large PR. + +## Guidelines + +- Each PR should do **one thing**: a single refactor, a single consolidation, a single feature addition. +- If a set of changes naturally stacks (B depends on A), create stacked PRs with the base set to the previous branch. +- Aim for PRs that are **easy to review in one sitting** — a reviewer should be able to understand the intent from the title alone. + +## Examples of good splits + +- Moving definitions to a new location (bulk import change) = 1 PR +- Consolidating a duplicate enum/constant to its canonical source = 1 PR per enum +- Adding a new method to a model + migrating callers to use it = 2 PRs + +## When creating stacked PRs + +1. Create a branch per logical change, each based on the previous. +2. Push all branches. +3. Open draft PRs with each PR's base set to the previous branch. +4. Note the dependency in the PR body (e.g. "Stacked on #123").