diff --git a/.agents/skills b/.agents/skills new file mode 120000 index 0000000000..6838a11606 --- /dev/null +++ b/.agents/skills @@ -0,0 +1 @@ +../.ai/skills \ No newline at end of file diff --git a/.ai/README.md b/.ai/README.md new file mode 100644 index 0000000000..d9b6c266f6 --- /dev/null +++ b/.ai/README.md @@ -0,0 +1,150 @@ +# RedisInsight AI Development Rules + +This directory contains the **single source of truth** for AI-assisted development rules and workflows in RedisInsight. + +## Overview + +This repository uses a centralized approach to AI development rules: + +- **`AGENTS.md`** (at repository root) - Entry point for AI agents with essential commands, testing instructions, and quick reference +- **`.ai/skills/`** - Detailed development standards as skills, plus skills from npm packages +- **`.ai/commands/`** - AI workflow commands and templates + +These standards are consumed by: + +- **Claude Code** (via `CLAUDE.md -> AGENTS.md` plus `.claude/commands/` and `.claude/skills/` symlinks) +- **Codex** (via `AGENTS.md` and the `.agents/skills` symlink) +- **GitHub Copilot** (via file: `.github/copilot-instructions.md`, optional) + +## Structure + +``` +AGENTS.md # 🎯 AI agent entry point +CLAUDE.md -> AGENTS.md # Claude Code entry point +.ai/ # Single source of truth +├── README.md # This file (human-readable overview) +├── skills/ # Development standards and agent skills +│ ├── code-quality/SKILL.md # Linting, TypeScript standards, naming, imports +│ ├── frontend/SKILL.md # React, Redux, styled-components, UI patterns +│ ├── backend/SKILL.md # NestJS, API patterns, DI, error handling +│ ├── testing/SKILL.md # Jest/Testing Library standards, faker, helpers +│ ├── e2e-testing/SKILL.md # Playwright standards, page objects, fixtures +│ ├── git-safety/SKILL.md # Protected-branch guardrails +│ ├── branches/SKILL.md # Branch naming +│ ├── commits/SKILL.md # Commit messages (Conventional Commits) +│ ├── pull-requests/SKILL.md # Pull request process +│ ├── feature-flags/SKILL.md # Feature flag lifecycle +│ ├── tsconfigs/SKILL.md # TypeScript configuration +│ ├── type-check-baselines/SKILL.md # TS error baseline workflow +│ └── redis-ui-components/ -> node_modules/@redis-ui/components/skills/redis-ui-components +│ ├── SKILL.md # Component catalog and usage patterns +│ └── references/ # Per-component API docs (Button, Select, etc.) +└── commands/ # AI workflow commands + ├── pr-plan.md # JIRA ticket implementation planning + ├── commit-message.md # Commit message generation + └── pull-request-review.md # PR review workflow + +# Symlinks +.claude/ + ├── commands/ -> ../.ai/commands/ # Claude Code (commands) + └── skills/ -> ../.ai/skills/ # Claude Code (skills) +.agents/ + └── skills -> ../.ai/skills # Codex (skills) +.github/copilot-instructions.md # GitHub Copilot reference (if used) +``` + +**Codex note**: Codex reads `AGENTS.md` for project instructions and discovers repo skills from `.agents/skills`. Do not create `.codex/rules/`: Codex `.rules` files are command execution policies, not Markdown development guidelines. + +## For AI Agents + +**Start here**: Read `AGENTS.md` at the repository root for: + +- Setup and build commands +- Code quality standards +- Testing instructions +- Git workflow guidelines +- Boundaries and best practices + +**Then refer to**: `.ai/skills/` for detailed guidelines on specific topics. + +## For Human Developers + +This directory contains comprehensive development standards used by AI coding assistants. Each topic lives in its own skill folder: + +- **Code Quality**: `.ai/skills/code-quality/SKILL.md` - TypeScript standards, import organization, best practices +- **Frontend**: `.ai/skills/frontend/SKILL.md` - React, Redux, styled-components, UI component usage +- **Backend**: `.ai/skills/backend/SKILL.md` - NestJS, dependency injection, API patterns +- **Testing**: `.ai/skills/testing/SKILL.md` - Jest/Testing Library patterns, faker, helpers +- **E2E Testing**: `.ai/skills/e2e-testing/SKILL.md` - Playwright standards, page objects +- **Git Safety**: `.ai/skills/git-safety/SKILL.md` - Protected-branch guardrails +- **Branches**: `.ai/skills/branches/SKILL.md` - Branch naming conventions +- **Commits**: `.ai/skills/commits/SKILL.md` - Commit message guidelines (Conventional Commits) +- **Pull Requests**: `.ai/skills/pull-requests/SKILL.md` - PR creation and review guidelines +- **Feature Flags**: `.ai/skills/feature-flags/SKILL.md` - Adding, promoting, and removing feature flags +- **TS Error Baselines**: `.ai/skills/type-check-baselines/SKILL.md` - TypeScript error baseline workflow +- **Redis UI Components**: `.ai/skills/redis-ui-components/` - Component API references, props, and usage examples (sourced from `@redis-ui/components` npm package via symlink) + +## MCP (Model Context Protocol) Setup + +AI tools can access external services (JIRA, Confluence, GitHub, Figma) via MCP configuration. + +### Initial Setup + +1. **Copy the example configuration:** + + ```bash + cp env.mcp.example .env.mcp + ``` + +2. **Get your Atlassian API token:** + + - Go to: https://id.atlassian.com/manage-profile/security/api-tokens + - Create a classic token by pressing the first "Create Token" button + - Copy the token + +3. **Edit `.env.mcp` with your credentials:** + + - Add your JIRA and Confluence API tokens + - Note: Figma MCP server uses OAuth authentication and doesn't require API keys + +4. **Verify your setup:** + + **For Cursor users:** + + - Restart Cursor to load the new MCP configuration + - Ask the AI: "Can you list all available MCP tools and test them?" + - The AI should be able to access JIRA, Confluence, GitHub, Figma, and other configured services + - **For Figma**: On first use, you'll be prompted to authenticate via OAuth flow in your browser + + **For Augment users:** + + ```bash + npx @augmentcode/auggie --mcp-config mcp.json "go over all my mcp tools and make sure they work as expected" + ``` + + **For GitHub Copilot users:** + + - Note: GitHub Copilot does not currently support MCP integration + - MCP services (JIRA, Confluence, etc.) will not be available in Copilot + +### Available MCP Services + +The `mcp.json` file configures these services: + +- **github** - GitHub integration (issues, PRs, repository operations) +- **memory** - Persistent context storage across sessions +- **sequential-thinking** - Enhanced reasoning for complex tasks +- **context-7** - Advanced context management +- **atlassian** - JIRA (RI-XXX tickets) and Confluence integration (requires API tokens in `.env.mcp`) +- **figma** - Figma design files, frames, and layers (uses OAuth authentication - no API key needed) + +## Updating These Rules + +To update AI standards: + +1. **Edit `SKILL.md` files under `.ai/skills/`** (never edit symlinked files directly) +2. **Update `AGENTS.md`** if you change commands, testing instructions, or the always-on rules block +3. Changes propagate to Claude Code automatically via the `.claude/` symlinks +4. Commit changes to version control + +**Remember**: These rules exist to maintain code quality and consistency. Follow them, but also use good judgment. diff --git a/.ai/commands/commit-message.md b/.ai/commands/commit-message.md new file mode 100644 index 0000000000..18f9852a95 --- /dev/null +++ b/.ai/commands/commit-message.md @@ -0,0 +1,112 @@ +# Commit Message Generation + +Generate concise, meaningful commit messages following RedisInsight conventions. + +## Format + +``` +(): + +[optional body] + +References: #RI-XXX +``` + +## Types & Scopes + +**Types**: `feat`, `fix`, `refactor`, `test`, `docs`, `chore`, `perf`, `ci` + +**Scopes**: `api`, `ui`, `e2e`, `deps` + +## Rules + +**DO:** +- ✅ Always include scope: `feat(api):`, `fix(ui):` +- ✅ Use imperative mood: "add feature" not "added feature" +- ✅ Start with lowercase after scope +- ✅ Keep subject under 250 characters +- ✅ Inspect all uncommitted files before generating + +**DON'T:** +- ❌ Omit scope +- ❌ Use past tense +- ❌ Add period at end +- ❌ Use multiple scopes (split into separate commits) + +## Examples + +```bash +feat(ui): add user profile editing +fix(api): resolve memory leak in connection pool +refactor(api): extract validation logic +test(e2e): add authentication tests +chore(deps): upgrade React to 18.2 +``` + +## Issue References + +**JIRA**: `References: #RI-123` or `Fixes #RI-123` +**GitHub**: `Fixes #123` or `Closes #123` + +## Process + +1. Run `git status && git diff` +2. Identify scope: API → `api`, UI → `ui`, Both → separate commits +3. Identify type: New → `feat`, Bug → `fix`, Improvement → `refactor` +4. Write description (what changed and why) +5. Add issue reference in body + +## Multiple Scopes + +Split into separate commits: + +```bash +# ✅ Good +git commit -m "feat(api): add user endpoint + +References: #RI-123" + +git commit -m "feat(ui): add user interface + +References: #RI-123" + +# ❌ Bad +git commit -m "feat(api,ui): add user feature" +``` + +## Output Format + +Present in copyable format: + +```markdown +Based on the changes, here's your commit message: + +\`\`\` +feat(api): add OAuth 2.0 authentication + +Implements OAuth flow with token management +and refresh token support. + +References: #RI-123 +\`\`\` +``` + +If multiple scopes: + +```markdown +Changes span multiple scopes. I recommend two commits: + +**Commit 1:** +\`\`\` +feat(api): add OAuth endpoints + +References: #RI-123 +\`\`\` + +**Commit 2:** +\`\`\` +feat(ui): add OAuth login interface + +References: #RI-123 +\`\`\` +``` diff --git a/.ai/commands/e2e-fix.md b/.ai/commands/e2e-fix.md new file mode 100644 index 0000000000..a7bd17a2e3 --- /dev/null +++ b/.ai/commands/e2e-fix.md @@ -0,0 +1,145 @@ +--- +description: Run E2E tests and fix any failures +argument-hint: +--- + +# Fix E2E Tests + +Run E2E tests matching a pattern, analyze failures, and fix them. + +**Follow all standards in `.ai/skills/e2e-testing/SKILL.md`** + +## Input + +**Test pattern** (required) - Test name or describe block pattern +- Examples: `"Analytics > Slow Log"`, `"should add string key"`, `"@smoke"` + +## Process + +### Step 1: Run the Tests + +```bash +cd tests/e2e-playwright +npx playwright test --grep "" --reporter=list 2>&1 | tail -50 +``` + +### Step 2: Analyze Failures + +If tests fail, check the error context file: + +```bash +cat test-results//error-context.md | head -150 +``` + +The error context contains: +- **Page snapshot** - Current UI state (element tree with refs) +- **Error message** - What assertion failed +- **Call log** - Playwright's action log + +### Step 3: Diagnose the Issue + +Common failure patterns: + +| Error | Likely Cause | Solution | +|-------|--------------|----------| +| `element(s) not found` | Wrong selector or element not rendered | Check snapshot for correct testid/role | +| `Timeout waiting for` | Element takes too long to appear | Add proper wait or check if element exists | +| `expected visible` | Element hidden or removed | Verify UI flow, check if dialog closed | +| `not.toBeVisible failed` | Element still visible | Wait for element to be removed | + +### Step 4: Explore UI if Needed + +If the error context doesn't reveal the issue, use Playwright MCP to explore: + +``` +browser_navigate_Playwright → http://localhost:8080 +browser_snapshot_Playwright +browser_click_Playwright → element, ref +``` + +### Step 5: Fix the Test + +Apply fixes following these priorities: + +1. **Fix selectors** - Use correct `data-testid` or role from snapshot +2. **Fix waits** - Replace `waitForTimeout` with proper element waits +3. **Fix test data** - Ensure unique prefixes to avoid conflicts with other tests +4. **Fix assertions** - Match actual UI behavior + +### Step 6: Verify the Fix + +```bash +cd tests/e2e-playwright +npx playwright test --grep "" --reporter=list 2>&1 | tail -30 +``` + +### Step 7: Run Linter and Type Check + +**REQUIRED before completing:** + +```bash +cd tests/e2e-playwright +npm run lint && npx tsc --noEmit +``` + +Both must pass. + +## Debugging Tips + +### Check Page Snapshot for Correct Selectors + +```yaml +# Look for data-testid in the snapshot +- button "Add" [ref=e123] [cursor=pointer] # Use getByRole('button', { name: 'Add' }) +- generic "my-testid" [ref=e456] # Use getByTestId('my-testid') +- treeitem "String keyname..." [ref=e789] # Use getByRole('treeitem', { name: /keyname/ }) +``` + +### Handle View Mode Differences + +Browser page has List view and Tree view with different element structures: + +```typescript +// List view uses gridcell +page.getByRole('gridcell', { name: keyName }) + +// Tree view uses treeitem +page.getByRole('treeitem', { name: new RegExp(keyName) }) + +// KeyList.getKeyRow() handles both +``` + +### Test Isolation Issues + +If test fails inconsistently, check for: +- Missing unique suffix in test data (conflicts with parallel runs) +- Missing cleanup in `afterEach` +- Shared state between tests (use `test.describe.serial` if needed) + +### Dropdown/Dialog Issues + +If clicking fails after interacting with dropdown: +```typescript +// Close dropdown before next action +await page.keyboard.press('Escape'); +``` + +## Example Usage + +``` +@e2e-fix "Analytics > Slow Log" +@e2e-fix "should add string key" +@e2e-fix "Browser > Key Details > String" +@e2e-fix "@smoke" +``` + +## Quick Reference + +| Command | Purpose | +|---------|---------| +| `npx playwright test --grep "pattern"` | Run matching tests | +| `npx playwright test --grep "pattern" --debug` | Run with inspector | +| `npx playwright show-trace ` | View test trace | +| `npm run lint` | Check for lint errors | +| `npx tsc --noEmit` | Check for type errors | + diff --git a/.ai/commands/e2e-generate.md b/.ai/commands/e2e-generate.md new file mode 100644 index 0000000000..976aa60051 --- /dev/null +++ b/.ai/commands/e2e-generate.md @@ -0,0 +1,132 @@ +--- +description: Explore a page using Playwright MCP and generate E2E tests for a Jira ticket +argument-hint: +--- + +# Generate E2E Tests + +Use Playwright MCP to explore a page, discover testable functionality, and generate E2E tests based on a Jira ticket. + +**Follow all standards in `.ai/skills/e2e-testing/SKILL.md`** + +**Reference:** @tests/e2e-playwright/TEST_PLAN.md + +## Prerequisites + +- App must be running at `http://localhost:8080` for Playwright exploration + +## Input + +1. **Ticket ID or URL** (required) + +## Process + +### Step 1: Fetch Jira Ticket Details + +Use the Jira API to get ticket information: +- Summary and description +- Acceptance criteria +- Related components/features + +### Step 2: Check Test Plan + +Review `tests/e2e-playwright/TEST_PLAN.md` to find related tests: +- ✅ = Already implemented (skip or verify) +- 🔲 = Not implemented (create new) + +### Step 3: Explore the Page with Playwright MCP + +Navigate to the relevant page based on the ticket's feature area: + +``` +browser_navigate_Playwright → url (e.g., http://localhost:8080) +browser_snapshot_Playwright +browser_click_Playwright → element, ref +browser_snapshot_Playwright (after each action) +``` + +Look for: +- `data-testid` attributes → use with `page.getByTestId()` +- Element roles (button, combobox, grid) → use with `page.getByRole()` +- Form field placeholders → use with `page.getByPlaceholder()` + +### Step 4: Check Existing Infrastructure + +```bash +ls tests/e2e-playwright/tests/ +ls tests/e2e-playwright/pages/ +ls tests/e2e-playwright/test-data/ +``` + +### Step 5: Generate Test Artifacts + +Based on exploration and ticket requirements, create/update: + +1. **Page Object** - `tests/e2e-playwright/pages/{feature}/{Feature}Page.ts` +2. **Test Data Factory** - `tests/e2e-playwright/test-data/{feature}/index.ts` +3. **Fixture** (if new page) - Update `tests/e2e-playwright/fixtures/base.ts` +4. **Test File** - `tests/e2e-playwright/tests/{feature}/{action}/*.spec.ts` + +### Step 6: Verify + +Run only the new tests using list reporter (no HTML report): + +```bash +cd tests/e2e-playwright +npx playwright test tests/main/{feature}/{action}/ --project=chromium --reporter=list +npm run lint && npx tsc --noEmit +``` + +**Note:** Use `--reporter=list` to avoid Playwright generating and hosting an HTML report. Use `--project=chromium` to run only browser tests (faster feedback). + +### Step 7: Update Test Plan + +Update `tests/e2e-playwright/TEST_PLAN.md` to match actual tests: + +- **Rename** test case names to match the actual test titles in spec files +- **Add** new test cases that were created +- **Delete** test cases that were removed or consolidated +- Mark implemented tests as ✅ + +Test case names in TEST_PLAN.md should exactly match the test titles in spec files (e.g., `should open Help Center and display all menu options`). + +## Exploration Checklist + +- [ ] Main page purpose and entry points +- [ ] Forms and their fields +- [ ] Buttons and their actions +- [ ] Lists/tables and CRUD operations +- [ ] Dialogs/modals triggered by actions +- [ ] Loading states and spinners +- [ ] Success/error toasts +- [ ] Empty states +- [ ] Validation messages +- [ ] `data-testid` attributes + +## Feature-to-URL Mapping + +| Feature | URL Pattern | +|---------|-------------| +| Database Management | `http://localhost:8080` | +| Browser | `http://localhost:8080/{dbId}/browser` | +| Workbench | `http://localhost:8080/{dbId}/workbench` | +| CLI | (Panel on any database page) | +| Pub/Sub | `http://localhost:8080/{dbId}/pub-sub` | +| Slow Log | `http://localhost:8080/{dbId}/analytics/slowlog` | +| Database Analysis | `http://localhost:8080/{dbId}/analytics/database-analysis` | +| Settings | `http://localhost:8080/settings` | + +**Note:** Replace `{dbId}` with an actual database UUID. + +## Example Usage + +``` +@e2e-generate RI-7992 +@e2e-generate https://redislabs.atlassian.net/browse/RI-7992 +``` + +The command will: +1. Fetch ticket details from Jira +2. Determine the relevant page/feature to test +3. Explore the UI at http://localhost:8080 +4. Generate appropriate E2E tests based on ticket requirements diff --git a/.ai/commands/generate-release-notes.md b/.ai/commands/generate-release-notes.md new file mode 100644 index 0000000000..22b10320bc --- /dev/null +++ b/.ai/commands/generate-release-notes.md @@ -0,0 +1,288 @@ +*** + +description: Generate release notes from JIRA tickets for a specific version +argument-hint: \[jira-filter-link-or-jql-or-csv-file] +--------------------------------------------------------------- + +Generate release notes for RedisInsight releases based on JIRA tickets. + +## Examples + +```bash +# Generate from JIRA filter link (PREFERRED) +generate-release-notes 3.0.3 "https:///jira/software/c/projects//issues?jql=project%20%3D%20..." + +# Generate from JIRA query (JQL) +generate-release-notes 3.0.2 "project = AND parent = " + +# Generate from CSV export +generate-release-notes 3.0.2 /path/to/jira-export.csv + +# Generate from ticket keys +generate-release-notes 3.0.2 ,, +``` + +**Always reference the GitHub releases page as the source of truth for format and style:** +https://github.com/redis/RedisInsight/releases + +Use existing releases (especially recent ones like 3.0.2, 3.0.0) as examples for: + +* Format and structure +* Tone and language +* Section organization +* Ticket reference format + +## 1. Get Version and Ticket Data + +**If version is not provided as an argument, prompt the user for it.** + +The version should be in semantic versioning format (e.g., `3.0.2`). + +**Ticket data can be provided in one of these ways:** + +1. **JIRA Filter Link** (PREFERRED): If a JIRA filter link is provided: + * **Detection**: Check if the input starts with `http://` or `https://` and contains `atlassian.net` and `jql=` + * **Example**: `https:///jira/software/c/projects//issues?jql=project%20%3D%20...` + * Extract the JQL query from the URL (decode URL-encoded parameters) + * **Use the JavaScript script `scripts/fetch-jira-tickets.js` to fetch all tickets matching the filter** (or JIRA MCP tools if available) + * For each ticket, fetch complete details including: + * Issue key, summary, type, status, priority + * Labels (check for "Github-Issue" label) + * Description + * All custom fields and metadata needed for categorization + * Process the tickets the same way as CSV data + +2. **JIRA Query (JQL)**: If a raw JQL query is provided (e.g., `project = AND parent = `), use the JIRA MCP tools to fetch tickets with full details + +3. **CSV File**: If a CSV file path is provided, parse it to extract ticket information + * To export from JIRA: Go to JIRA → Search for issues → Run your JQL query → Export → CSV + * The CSV will contain all ticket information needed for generation + +4. **Ticket Keys**: If specific ticket keys are provided (e.g., `,`), fetch each ticket individually with full details + +## 2. Fetch and Categorize Tickets + +For each ticket, analyze its essence to categorize it: + +### Exclusion Rules + +**Exclude entirely (do not include in any section):** + +* **Spike tickets**: If issue type is "Spike", exclude from release notes +* **POC tickets**: If "POC" appears in the title or description (indicating proof-of-concept that is not implemented), exclude from release notes +* These tickets are not ready for release and should not be mentioned + +### Categorization Logic + +**Bug indicators:** + +* Issue type contains "bug" or "defect" +* Summary contains: "fix", "bug", "error", "issue", "broken", "crash", "fail" +* Labels contain "bug" or "defect" + +**IMPORTANT: Bugs/Bug fixes section filter:** + +* **Only tickets with the "Github-Issue" label should be included in the Bugs/Bug fixes section** +* When processing tickets from JIRA query or CSV, filter bugs to only include those with the "Github-Issue" label +* **Include all bugs that have the "Github-Issue" label**—every such ticket must appear in the Bugs section with no limit or additional filtering +* Other bug tickets (without this label) should be excluded from the Bugs/Bug fixes section +* **Bugs with Github-Issue label should ONLY appear in the Bugs section, NOT in Headlines or Details sections** +* **Always list each of these bugs with the GitHub issue link**: For every ticket in the Bugs section (tickets with "Github-Issue" label), output the line in the form `[#ISSUE-NUMBER](https://github.com/redis/RedisInsight/issues/ISSUE-NUMBER) [Short description]`. Resolve the GitHub issue number from: (1) JIRA labels such as `Github-4658` (use the number part), (2) JIRA description or linked PR body (e.g. "References #5381", "Closes #5382"), or (3) search on GitHub (repo: redis/RedisInsight) for the issue or PR that matches the bug (e.g. by JIRA key like RI-7894 or by summary). If the number cannot be determined, still include the short description but add a note to look up the link. + +**Feature indicators:** + +* Issue type contains: "story", "feature", "epic", "enhancement" +* Summary contains: "add", "implement", "new", "introduce", "support", "enable" +* Labels contain "feature" or "enhancement" + +**Improvement indicators:** + +* Issue type contains: "task", "improvement" +* Summary contains: "improve", "enhance", "update", "optimize", "refactor" +* Labels contain "improvement" + +## 3. Generate Release Notes + +Use the template from `docs/release-notes/RELEASE_NOTES_TEMPLATE.md` as a reference. + +### Format Selection + +* **If only bugs (with "Github-Issue" label)**: Use simple "Bug fixes" section only; include every ticket that has the "Github-Issue" label +* **If features/improvements exist**: Use full format with "Headlines", "Details", and "Bugs" sections + * Note: The "Bugs" section must include all tickets with the "Github-Issue" label (include every one) + +### Section Organization Rules + +**IMPORTANT: Avoid duplication between sections:** + +* **Tickets with "Github-Issue" label**: These should **ONLY** appear in the "Bugs" section, never in "Headlines" or "Details" sections +* **No duplication**: Items in the Bugs section must not appear in Headlines or Details sections +* **Headlines and Details relationship**: + * Headlines should contain short summaries of the most important user-facing features and improvements + * Details can expand on Headlines items with more information, or include additional features/improvements not mentioned in Headlines + * The same item can appear in both Headlines (short summary) and Details (full description), but items from Bugs section must not appear in either + +### Release Notes Structure + +**Reference format from GitHub releases:** https://github.com/redis/RedisInsight/releases + +```markdown +# [VERSION] ([MONTH] [YEAR]) + +[Release description based on content] + +### Headlines (if features exist - see 3.0.0 example) +* [Top 3-5 most important items - user-facing features or critical improvements] + +### Details (if features/improvements exist - see 3.0.0 example) +* [Short description of what was added/improved] (for JIRA tickets, don't include ticket ID) +* [#ISSUE-NUMBER](https://github.com/redis/RedisInsight/issues/ISSUE-NUMBER) [Summary] (for GitHub issues, use link format) + +### Bugs (if features exist) OR Bug fixes (if only bugs - see 3.0.2 example) +* **IMPORTANT: Include all tickets with the "Github-Issue" label in this section (every one, no limit). Always list each bug with its GitHub issue link.** +* Each line must be: `[#ISSUE-NUMBER](https://github.com/redis/RedisInsight/issues/ISSUE-NUMBER) [Short description of problem and fix]` +* Resolve ISSUE-NUMBER from JIRA labels (e.g. Github-4658 → 4658), ticket/PR references, or GitHub search if needed. + +**SHA-512 Checksums** + +https://redis.io/docs/latest/develop/tools/insight/release-notes/v.[VERSION]/ + +**Full Changelog**: https://github.com/redis/RedisInsight/compare/[LAST_RELEASED]...[VERSION] +``` + +**Important formatting notes from GitHub releases:** + +* **For the Bugs section (tickets with "Github-Issue" label)**: Always list each bug with its GitHub issue link: `[#](https://github.com/redis/RedisInsight/issues/) [Short description]`. Resolve the issue number from JIRA labels (e.g. `Github-4658`), from "References #NNNN" / "Closes #NNNN" in linked PRs or descriptions, or by searching GitHub (repo: redis/RedisInsight) for the matching issue. +* **For other JIRA tickets** (Headlines/Details): Do NOT include ticket IDs. Provide a very short description of what was added or fixed. +* **For GitHub issues** (when referenced elsewhere): Use actual links in format `[#](https://github.com/redis/RedisInsight/issues/)` (not just `#` or `#`). +* Use "SHA-512 Checksums" for all releases +* Keep descriptions concise and user-focused +* Headlines should highlight the most impactful user-facing changes + +### Release Description + +**Examples from GitHub releases:** + +* **Major releases** (x.0.0): "This is the General Availability (GA) release of Redis Insight \[version], a major version upgrade that introduces \[key themes]." + * See 3.0.0 example: mentions "new UI experience, new navigation architecture, and foundational improvements" +* **Patch releases with only bugs**: + * Check ticket priorities to determine description: + * If only high/critical priority bugs: "This maintenance patch release includes critical bug fixes for Redis Insight \[major.minor].0." + * If only medium/low priority bugs: "This maintenance patch release includes non-critical bug fixes for Redis Insight \[major.minor].0." + * If both critical and non-critical: "This maintenance patch release includes critical and non-critical bug fixes for Redis Insight \[major.minor].0." + * See 3.0.2 example +* **Patch releases with features**: "This release includes new features, improvements, and bug fixes for Redis Insight." + * See 2.64, 2.62, 2.60 examples for format with "Highlights" and "Details" sections + +## 4. Generate All Release Note Formats + +After generating the main release notes, create **two different formats** for different platforms: + +### 4.1 GitHub/Redis Docs Format + +Save the generated release notes to `RELEASE_NOTES_[VERSION].md` in the repository root. + +**Important: Links** + +* **Checksums link**: Use format `https://redis.io/docs/latest/develop/tools/insight/release-notes/v.[VERSION]/` + * Example for 3.0.3: `https://redis.io/docs/latest/develop/tools/insight/release-notes/v.3.0.3/` +* **Full Changelog link**: Use format `https://github.com/redis/RedisInsight/compare/[LAST_RELEASED]...[VERSION]` + * Example for 3.0.3 (if last release was 3.0.2): `https://github.com/redis/RedisInsight/compare/3.0.2...3.0.3` + * Determine the last released version by checking GitHub releases or repository tags + +### 4.2 Store Format (App Store & Microsoft Store) + +Save to `RELEASE_NOTES_STORE_[VERSION].md` in the repository root. + +**IMPORTANT:** Reuse the same content from the GitHub/Redis Docs format (`RELEASE_NOTES_[VERSION].md`), but apply different formatting. Only the formatting changes - the content (sections, descriptions, items) should remain the same. + +**Note:** This single file is used for both App Store and Microsoft Store as they have identical format requirements. + +**Format requirements (formatting changes only):** + +* Plain text only (no markdown formatting) +* Section header: "Bug fixes" (if only bugs) or appropriate section name (if features exist) - keep the same section names from GitHub format +* Use bullet points with `•` character (not `*`) +* No version number or date header +* No links (remove SHA-512 Checksums and Full Changelog sections) +* No markdown headers (`#`, `###`) +* No bold formatting (`**`) +* Just the section headers and bullet points - same content, different formatting + +**Example format:** + +``` +Bug fixes + +• Fixed default database sorting order to display most recently used databases at the top +• Restored missing Pub/Sub functionality including message clear option, full message display with line wrapping, and descending chronological order (most recent messages first) +``` + +**If features/improvements exist, use appropriate section headers:** + +``` +Features + +• [Feature description] + +Improvements + +• [Improvement description] + +Bug fixes + +• [Bug fix description] +``` + +## 5. Display Summary + +Show a summary of: + +* Total tickets processed +* Number of bugs, features, and improvements +* Which format was used (simple vs. full) +* File locations for all formats: + * GitHub/Redis Docs: `RELEASE_NOTES_[VERSION].md` + * App Store & Microsoft Store: `RELEASE_NOTES_STORE_[VERSION].md` + +## JIRA Filter Link Processing + +When a JIRA filter link is provided: + +1. **Parse the URL and fetch tickets**: Extract the JQL query from the `jql` parameter in the URL and use the JavaScript script `scripts/fetch-jira-tickets.js` to fetch all tickets matching the query + * Example URL: `https:///jira/software/c/projects//issues?jql=project%20%3D%20%20AND%20status%20%3D%20Closed` + * Extract and decode: `project = AND status = Closed` + * **Use `node scripts/fetch-jira-tickets.js ` to fetch tickets** (the script uses JIRA REST API with credentials from `.env.mcp`) + * Alternatively, if JIRA MCP tools are available, use them (check with `list_mcp_resources`) such as `jira_search` or `jira_get_project_issues` + +2. **Fetch full details**: For each ticket returned, fetch complete information: + * **Basic fields**: key, summary, type, status, priority, description + * **Labels**: Extract all labels and check for "Github-Issue" label (critical for filtering) + * **Custom fields**: Any additional fields needed for categorization + * **Links**: Check for linked GitHub pull requests or issues + * **Metadata**: Created date, updated date, resolved date, assignee, reporter + +3. **Transform to CSV-like structure**: Convert the fetched ticket data into a structure similar to CSV format: + ```javascript + { + 'Issue key': '', + 'Summary': 'Fix default database sorting...', + 'Issue Type': 'Bug', + 'Status': 'Closed', + 'Priority': 'Medium', + 'Labels': ['Github-Issue', 'Github-Issue-Notification'], + 'Description': 'Full description text...', + // ... other fields + } + ``` + +4. **Process**: Use the same categorization and filtering logic as CSV processing + +## Notes + +* Keep summaries concise, user-focused, and descriptive +* For Headlines section, prioritize the most impactful user-facing changes (see 3.0.0 example) +* Ensure all closed tickets are included if they match the criteria +* **Always check GitHub releases page** before generating to ensure consistency with published format: + https://github.com/redis/RedisInsight/releases +* Match the tone and style of existing releases (professional, clear, user-focused) diff --git a/.ai/commands/pr-plan.md b/.ai/commands/pr-plan.md new file mode 100644 index 0000000000..ce3d90fcc4 --- /dev/null +++ b/.ai/commands/pr-plan.md @@ -0,0 +1,328 @@ +--- +description: Analyze a JIRA ticket and create a detailed implementation plan +argument-hint: +--- + +Create a comprehensive implementation plan for a JIRA ticket. + +## 1. Fetch JIRA Ticket + +**If ticket ID is not provided as an argument, prompt the user for it.** + +Fetch all the information from the ticket, its comments, linked documents, and parent ticket. + +Use the `jira` tool to fetch the ticket details. + +## 4. Create Implementation Plan + +Use `sequential-thinking` tool for complex analysis. Break down into thoughts: + +### Thought 1-5: Requirements Analysis + +- Parse acceptance criteria into specific tasks +- Identify functional requirements +- Identify non-functional requirements (performance, security, cost) +- Map requirements to system components +- Identify dependencies and blockers + +### Thought 6-10: Architecture Planning + +- Determine which services are affected +- Identify new components needed +- Identify existing components to modify +- Plan data flow and interactions +- Consider error handling and edge cases + +### Thought 16-20: Implementation Breakdown + +- Break work into logical phases +- Identify dependencies between phases +- Consider testing strategy for each phase +- Plan for incremental delivery + +### Thought 21-25: Testing Strategy + +- Identify test scenarios from acceptance criteria +- Plan unit tests (behavior-based, not implementation) +- Plan integration tests +- Consider edge cases and error scenarios +- Plan test data needs + +### Thought 26-30: Risk Assessment + +- Identify technical risks +- Identify integration risks +- Identify timeline risks +- Identify knowledge gaps +- Plan mitigation strategies + +## 5. Generate Implementation Plan Document + +**CRITICAL: You MUST create and save a plan document. This is NOT optional.** + +Create a comprehensive Markdown document and save it to `docs/pr-plan-{ticket-id}-{brief-description}.md` using the `write` tool. + +**IMPORTANT: Planner Detection** +- Detect which AI tool is being used (Cursor, Augment, or other) +- Set the **Planner** field to: + - "Cursor Agent" if running in Cursor + - "Augment Agent" if running in Augment + - "[Tool Name] Agent" for other tools +- You can infer the tool from context, user messages, or environment + +**The document structure MUST include all sections below:** + +```markdown +# Implementation Plan: [Ticket Title] + +**JIRA Ticket:** [MOD-XXXXX](https://redislabs.atlassian.net/browse/MOD-XXXXX) +**Epic:** [EPIC-XXX](link) (if applicable) +**Parent:** [PARENT-XXX](link) (if applicable) +**Plan Date:** [Date] +**Planner:** [Detect and set: Cursor Agent / Augment Agent / [Tool Name] Agent] + +--- + +## Executive Summary + +**Components Affected:** + +- [component name] + +**Key Risks:** + +1. [Risk with mitigation] +2. [Risk with mitigation] +3. [Risk with mitigation] + +--- + +## 1. Requirements Summary + +**Story (Why):** +[Quote or summarize the story from the ticket] + +**Acceptance Criteria (What):** + +1. [AC1] +2. [AC2] +3. [AC3] + +**Functional Requirements:** + +- [Requirement 1] +- [Requirement 2] + +**Non-Functional Requirements:** + +- [NFR 1 - e.g., Performance: <100ms response time] +- [NFR 2 - e.g., Security: Requires authentication] + +**Resources Provided:** + +- [Link 1: Description] +- [Link 2: Description] + +## 2. Current State Analysis + +### Frontend Changes + +**Components to Modify:** + +- [Component 1]: [What changes are needed] +- [Component 2]: [What changes are needed] + +**Components to Create:** + +- [Component 1]: [Why it's needed] +- [Component 2]: [Why it's needed] + +**Components to Reuse:** + +- [Component 1]: [How it will be used] +- [Component 2]: [How it will be used] + +### Backend Changes + +**Services to Modify:** + +- [Service 1]: [What changes are needed] +- [Service 2]: [What changes are needed] + +**Services to Create:** + +- [Service 1]: [Why it's needed] +- [Service 2]: [Why it's needed] + +**APIs to Modify:** + +- [API 1]: [What's changing] +- [API 2]: [What's changing] + +**APIs to Create:** + +- [API 1]: [Why it's needed] +- [API 2]: [Why it's needed] + +**Data Models:** + +- [Model 1]: [Description and whether it needs extension] +- [Model 2]: [Description and whether it needs extension] + +**Repositories:** + +- [Repo 1]: [Description and whether it can be reused] + +--- + +## 3. Implementation Plan + +### Phase 1: [Phase Name] + +**Goal:** [What this phase achieves] + +**Tasks:** + +1. [ ] [Task 1 - specific, actionable] + - Files: [List of files to create/modify] + - Acceptance: [How to verify this task is done] +2. [ ] [Task 2] + - Files: [List of files] + - Acceptance: [Verification criteria] + +**Deliverables:** + +- [Deliverable 1] +- [Deliverable 2] + +**Testing:** + +- [Test scenario 1] +- [Test scenario 2] + +### Phase 2: [Phase Name] + +[Same structure as Phase 1] + +### Phase 3: [Phase Name] + +[Same structure as Phase 1] + +--- + +## 5. Testing Strategy + +### Test Scenarios (from Acceptance Criteria) + +**AC1: [Acceptance Criterion]** + +- Test Scenario: [Given-When-Then] +- Test Type: Unit/Integration +- Test Location: [File path] + +**AC2: [Acceptance Criterion]** + +- Test Scenario: [Given-When-Then] +- Test Type: Unit/Integration +- Test Location: [File path] + +### Edge Cases and Error Scenarios + +1. **[Edge Case 1]** + + - Scenario: [Description] + - Expected Behavior: [What should happen] + - Test: [How to test] + +2. **[Error Scenario 1]** + - Scenario: [Description] + - Expected Error: [Error type/code] + - Test: [How to test] + +### Test Data Needs + +- [Test data 1]: [Description] +- [Test data 2]: [Description] + +--- + +## 6. Risk Assessment and Mitigation + +### Technical Risks + +| Risk | Likelihood | Impact | Mitigation | +| -------- | --------------- | --------------- | --------------------- | +| [Risk 1] | High/Medium/Low | High/Medium/Low | [Mitigation strategy] | +| [Risk 2] | High/Medium/Low | High/Medium/Low | [Mitigation strategy] | + +### Integration Risks + +| Risk | Likelihood | Impact | Mitigation | +| -------- | --------------- | --------------- | --------------------- | +| [Risk 1] | High/Medium/Low | High/Medium/Low | [Mitigation strategy] | + +### Timeline Risks + +| Risk | Likelihood | Impact | Mitigation | +| -------- | --------------- | --------------- | --------------------- | +| [Risk 1] | High/Medium/Low | High/Medium/Low | [Mitigation strategy] | + +### Knowledge Gaps + +- [Gap 1]: [What we don't know and how to find out] +- [Gap 2]: [What we don't know and how to find out] +``` + +--- + +## 6. Save the Plan Document + +**CRITICAL: You MUST save the plan document using the `write` tool.** + +1. **Generate the complete plan document** following the structure in section 5 +2. **Save it** to `docs/pr-plan-{ticket-id}-{brief-description}.md` using `write` tool +3. **Verify the file was created** by confirming the write tool succeeded + +**Example filename:** `docs/pr-plan-MOD-11280-dp-services-clean-architecture.md` + +--- + +## 7. Follow-up Actions + +After saving the plan document: + +1. **Confirm document was saved** - Show the file path to the user +2. **Summarize key findings** for the user: + - Key risks + - Recommended approach + - **Confirm plan document was saved** (file path) +3. **Ask if user wants to:** + - Review the plan document + - Proceed with implementation + +--- + +## Important Notes + +- **ALWAYS save the plan document** - use `write` tool to save to `docs/pr-plan-{ticket-id}-{brief-description}.md` +- **Use main branch as baseline** - all analysis should be against current main +- **Be specific and actionable** - every task should be clear and verifiable +- **Consider PR stacking** - plan for small, reviewable PRs (see `.ai/skills/pull-requests/SKILL.md`). plan breaking the implementation in a stack of PRs. +- **Follow all project standards** - reference skills in `.ai/skills/` +- **Document assumptions** - if anything is unclear, document the assumption made +- **Identify blockers early** - surface dependencies and knowledge gaps upfront + +## Execution Order Summary + +**The correct order of operations is:** + +1. ✅ Fetch JIRA ticket +2. ✅ Analyze current codebase state +3. ✅ Create implementation plan using sequential-thinking +4. ✅ Generate implementation plan document content +5. ✅ **Save plan document to `docs/pr-plan-{ticket-id}-{brief-description}.md`** (CRITICAL - use write tool) +6. ✅ Present results to user and confirm document location + +**Do NOT skip step 5 - it is mandatory and must be done during command execution.** + +**Step 5 is MANDATORY:** You MUST use the `write` tool to save the plan document. Do NOT just present the plan to the user without saving it. diff --git a/.ai/commands/pull-request-review.md b/.ai/commands/pull-request-review.md new file mode 100644 index 0000000000..5bd884d866 --- /dev/null +++ b/.ai/commands/pull-request-review.md @@ -0,0 +1,205 @@ +# PR Review Command + +## Purpose + +Reviews code changes in the current branch against requirements, best practices, and project standards. + +## Usage + +```bash +/pr:review +``` + +**Examples**: + +- JIRA ticket: `/pr:review RI-1234` +- GitHub issue: `/pr:review 456` + +## Prerequisites + +1. Checkout the branch to review locally +2. Ensure the ticket ID is valid and accessible +3. Have JIRA MCP tool configured (if using JIRA integration) + +## Process + +### 1. Gather Context + +- Fetch JIRA ticket details (if available) +- Read requirements and acceptance criteria +- Identify affected files in the PR +- Review recent commits + +### 2. Code Analysis + +Analyze the changes against: + +- **Code Quality**: Linting rules, TypeScript types, complexity +- **Testing**: Test coverage, test quality, edge cases +- **Performance**: Rendering optimizations +- **Security**: Input validation, XSS prevention, credential handling +- **Accessibility**: ARIA labels, keyboard navigation, semantic HTML +- **Best Practices**: React patterns, Redux usage, NestJS conventions + +### 3. Requirements Check + +- Verify all acceptance criteria are met +- Check for missing functionality +- Validate edge case handling +- Ensure proper error messages + +### 4. Testing Validation + +- Unit test coverage (80% minimum) +- Integration tests for API endpoints +- Component tests for React components +- E2E tests for critical flows +- No fixed timeouts or magic numbers +- Use of faker for test data + +### 5. Generate Report + +Create a markdown report in `docs/reviews/pr--.md` with: + +**Note**: Use appropriate ticket reference format: + +- JIRA tickets: `pr-RI-1234-2024-11-20.md` +- GitHub issues: `pr-456-2024-11-20.md` + +Report should include: + +- **Summary**: Overview of changes +- **Strengths**: What was done well +- **Issues**: Categorized by severity (Critical, High, Medium, Low) +- **Suggestions**: Improvements and optimizations +- **Requirements Coverage**: Acceptance criteria checklist +- **Testing Assessment**: Coverage and quality analysis +- **Risk Assessment**: Potential issues or impacts + +## Review Checklist + +### Code Quality + +- [ ] No linting errors +- [ ] TypeScript types are proper (no `any` without justification) +- [ ] Code follows project conventions +- [ ] No console.log statements +- [ ] Import order is correct +- [ ] Cognitive complexity within limits +- [ ] No duplicate code + +### Testing + +- [ ] Unit tests added/updated +- [ ] Test coverage meets thresholds +- [ ] Tests use faker for data generation +- [ ] No fixed timeouts in tests +- [ ] Edge cases are tested +- [ ] Mocks are properly configured + +### React/Frontend (if applicable) + +- [ ] Functional components with hooks +- [ ] Proper state management (Redux vs local) +- [ ] Effects cleanup properly +- [ ] No unnecessary re-renders +- [ ] Accessibility considerations +- [ ] Styled-components for styling (no new SCSS modules) +- [ ] Proper error boundaries +- [ ] Component folder structure follows guidelines + +### NestJS/Backend (if applicable) + +- [ ] Dependency injection used properly +- [ ] DTOs for validation +- [ ] Proper error handling +- [ ] Swagger documentation +- [ ] Service layer separation +- [ ] Database transactions where needed + +### Performance + +- [ ] No performance regressions +- [ ] Large lists virtualized +- [ ] Routes lazy loaded +- [ ] Expensive operations memoized +- [ ] Bundle size impact acceptable + +### Security + +- [ ] Input validation +- [ ] Output sanitization +- [ ] No sensitive data in logs +- [ ] Proper authentication/authorization +- [ ] SQL injection prevention (if applicable) + +### Documentation + +- [ ] README updated if needed +- [ ] Complex logic documented +- [ ] API documentation updated +- [ ] Breaking changes noted + +## Example Output + +**Note**: Use appropriate ticket format (RI-1234 for JIRA or #456 for GitHub issues) + +```markdown +# PR Review: RI-1234 - Add User Profile Editing + +**Date**: 2024-11-20 +**Reviewer**: AI Assistant +**Branch**: feature/RI-1234/user-profile-editing + +## Summary + +This PR implements user profile editing functionality including UI components, +API endpoints, and data persistence. The implementation follows project +standards with good test coverage. + +## High Priority Issues + +1. **Missing Input Validation** (Security) + - File: `redisinsight/api/src/user/user.service.ts:45` + - Issue: Email validation missing on backend + - Recommendation: Add class-validator decorator to DTO + +## Medium Priority Issues + +1. **Performance Concern** (Performance) + + - File: `redisinsight/ui/src/components/UserProfile.tsx:78` + - Issue: Inline function in render + - Recommendation: Extract to useCallback + +2. **Test Flakiness Risk** (Testing) + - File: `redisinsight/ui/src/components/UserProfile.spec.tsx:45` + - Issue: Direct state check without waitFor + - Recommendation: Wrap assertion in waitFor + +## Low Priority Issues + +1. **Code Style** (Style) + - File: Multiple files + - Issue: Inconsistent import ordering + - Recommendation: Run `yarn prettier:fix` + +## Risk Assessment + +**Low Risk** - Well-tested implementation with minor issues that can be +addressed before merge. No breaking changes or security vulnerabilities. + +## Recommendation + +**Approve with comments** - Address high priority issues before merging. +Consider suggestions for future improvements. +``` + +## Notes + +- Focus on constructive feedback +- Prioritize issues by severity +- Be specific with file locations and line numbers +- Provide actionable recommendations +- Balance criticism with recognition of good practices +- Consider the broader impact of changes diff --git a/.ai/skills/backend/SKILL.md b/.ai/skills/backend/SKILL.md new file mode 100644 index 0000000000..1b300ed790 --- /dev/null +++ b/.ai/skills/backend/SKILL.md @@ -0,0 +1,240 @@ +--- +name: backend +description: >- + NestJS backend development patterns for the RedisInsight API: + module structure, services, controllers, DTOs, dependency injection, + and error handling. Use when editing any file under + redisinsight/api/**, writing or modifying NestJS modules, + controllers, services, DTOs, providers, or when the user mentions + the backend, API, or NestJS. +--- + + +# Backend Development (NestJS/API) + +## Module Structure + +### NestJS Architecture + +- Follow **modular architecture** (feature-based modules) +- Use **dependency injection** throughout +- **Separate concerns**: Controllers, Services, Repositories +- Use **DTOs** for validation and data transfer +- Apply **proper error handling** with NestJS exceptions + +### Module Folder Structure + +Each feature module in its own directory under `api/src/`: + +``` +feature/ +├── feature.module.ts # Module definition +├── feature.controller.ts # REST endpoints +├── feature.service.ts # Business logic +├── feature.service.spec.ts # Service tests +├── feature.controller.spec.ts # Controller tests +├── feature.types.ts # Interfaces and types related to the feature +├── dto/ # Data transfer objects +│ ├── create-feature.dto.ts +│ ├── update-feature.dto.ts +│ └── feature.dto.ts +├── entities/ # TypeORM entities +├── repositories/ # Custom repositories +├── exceptions/ # Custom exceptions +├── guards/ # Feature-specific guards +├── decorators/ # Custom decorators +└── constants/ # Feature constants +``` + +### File Naming + +- **Modules**: `feature.module.ts` +- **Controllers**: `feature.controller.ts` +- **Services**: `feature.service.ts` +- **DTOs**: `create-feature.dto.ts`, `update-feature.dto.ts` +- **Entities**: `feature.entity.ts` +- **Interfaces and types**: `feature.types.ts` +- **Tests**: `feature.service.spec.ts` +- **Constants**: `feature.constants.ts` +- **Exceptions**: `feature-not-found.exception.ts` + +### Constants Organization + +Store feature-specific constants in dedicated constants file: + +```typescript +export const FEATURE_CONSTANTS = { + MAX_NAME_LENGTH: 100, + DEFAULT_PAGE_SIZE: 20, +} as const; + +export const FEATURE_ERROR_MESSAGES = { + NOT_FOUND: 'Feature not found', + INVALID_INPUT: 'Invalid feature data', +} as const; +``` + +### Imports Order + +1. Node.js built-in modules +2. External dependencies (`@nestjs/*`, etc.) +3. Internal modules (using `src/*` alias — the backend's self-reference into `redisinsight/api/src/*`) +4. Local relative imports + +## Service Layer + +### Service Pattern + +- Inject dependencies via constructor +- Use TypeORM repositories +- Handle errors with NestJS exceptions +- Use Logger for important operations +- Keep business logic in services (not controllers) + +### Dependency Injection + +Always inject dependencies via constructor with proper decorators: + +```typescript +@Injectable() +export class UserService { + constructor( + @InjectRepository(User) + private readonly userRepository: Repository, + private readonly emailService: EmailService, + ) {} +} +``` + +## Controller Layer + +### Controller Pattern + +- Keep controllers thin (delegate to services) +- Use proper HTTP decorators (`@Get`, `@Post`, etc.) +- Use `@Body`, `@Param`, `@Query` for inputs +- Apply guards with `@UseGuards()` +- Document with Swagger decorators + +### HTTP Status Codes + +- Use `@HttpCode()` decorator for non-standard codes +- Return appropriate status codes (200, 201, 204, 400, 404, etc.) + +## Data Transfer Objects (DTOs) + +### Validation + +Use `class-validator` decorators for validation: + +- `@IsString()`, `@IsNumber()`, `@IsEmail()` +- `@IsNotEmpty()`, `@IsOptional()` +- `@MinLength()`, `@MaxLength()` +- `@Min()`, `@Max()` + +### Swagger Documentation + +Use `@ApiProperty()` and `@ApiPropertyOptional()` for Swagger docs. + +## Error Handling + +### NestJS Exceptions + +Use appropriate exception types: + +- `NotFoundException` - 404 +- `BadRequestException` - 400 +- `UnauthorizedException` - 401 +- `ForbiddenException` - 403 +- `ConflictException` - 409 +- `InternalServerErrorException` - 500 + +### Custom Exceptions + +**Prefer custom exceptions over generic ones** when you need: + +- Consistent error codes for frontend handling +- Specific error messages from constants +- Consistent error structure across the codebase + +Create custom exceptions following existing patterns: + +```typescript +// src/modules/feature/exceptions/feature-invalid.exception.ts +import { + HttpException, + HttpExceptionOptions, + HttpStatus, +} from '@nestjs/common'; +import ERROR_MESSAGES from 'src/constants/error-messages'; +import { CustomErrorCodes } from 'src/constants'; + +export class FeatureInvalidException extends HttpException { + constructor( + message = ERROR_MESSAGES.FEATURE_INVALID, + options?: HttpExceptionOptions, + ) { + const response = { + message, + statusCode: HttpStatus.BAD_REQUEST, + error: 'FeatureInvalid', + errorCode: CustomErrorCodes.FeatureInvalid, + }; + + super(response, response.statusCode, options); + } +} +``` + +### Error Logging + +```typescript +private readonly logger = new Logger(ServiceName.name) + +this.logger.error('Error message', error.stack, { context }) +``` + +## Redis Integration + +### Redis Service Pattern + +- Use RedisClient from `src/modules/redis` +- Handle errors gracefully +- Log Redis operations +- Use try-catch for error handling + +## Code Quality + +### Cognitive Complexity (≤ 15) + +- Use early returns to reduce nesting +- Extract complex logic to separate functions +- Avoid deeply nested conditions + +### No Duplicate Strings + +Extract repeated strings to constants in constants file. + +## API Documentation (Swagger) + +### Required Decorators + +- `@ApiTags()` - Group endpoints +- `@ApiOperation()` - Describe operation +- `@ApiResponse()` - Document responses +- `@ApiParam()` - Document params +- `@ApiQuery()` - Document query params +- `@ApiBearerAuth()` - Auth requirement + +## Checklist + +- [ ] Services use dependency injection +- [ ] DTOs have validation decorators +- [ ] Controllers have Swagger documentation +- [ ] Proper HTTP status codes used +- [ ] Error handling with appropriate exceptions +- [ ] Logging for important operations +- [ ] Transactions for related DB operations +- [ ] Configuration via ConfigService +- [ ] Guards for authentication/authorization +- [ ] Cognitive complexity ≤ 15 diff --git a/.ai/skills/branches/SKILL.md b/.ai/skills/branches/SKILL.md new file mode 100644 index 0000000000..1b604be270 --- /dev/null +++ b/.ai/skills/branches/SKILL.md @@ -0,0 +1,54 @@ +--- +name: branches +description: >- + Create and name git branches following project conventions. Use when + creating branches, checking out new branches, or the user mentions + branch naming. +--- + +# Branch Naming Conventions + +Use lowercase kebab-case with type prefix and issue/ticket identifier. + +```bash +# Pattern: // + +# INTERNAL (JIRA - RI-XXX) +feature/RI-123/add-user-profile +bugfix/RI-789/memory-leak +fe/feature/RI-567/add-dark-mode +be/bugfix/RI-345/fix-redis-connection +docs/RI-333/update-docs +test/RI-444/add-unit-tests +e2e/RI-555/add-integration-tests + +# OPEN SOURCE (GitHub - XXX) +feature/123/add-export-feature +bugfix/789/fix-connection-timeout + +# Special branches +release/v2.0.0 +ric/RI-666/custom-prefix +``` + +## Branch Types + +- `feature/` - New features and refactoring (affects multiple areas) +- `bugfix/` - Bug fixes (affects multiple areas) +- `fe/feature/` - Frontend-only features (only `redisinsight/ui/` folder) +- `fe/bugfix/` - Frontend-only bug fixes (only `redisinsight/ui/` folder) +- `be/feature/` - Backend-only features (only `redisinsight/api/` folder) +- `be/bugfix/` - Backend-only bug fixes (only `redisinsight/api/` folder) +- `docs/` - Documentation changes +- `test/` - Test-related changes +- `e2e/` - End-to-end test changes +- `release/` - Release branches +- `ric/` - Custom prefix for special cases + +**Note:** When a bug fix affects only the `redisinsight/ui/` folder, use `fe/bugfix/` prefix instead of `bugfix/`. + +## Issue References + +- **Internal**: `RI-XXX` (JIRA ticket) +- **Open Source**: `XXX` (GitHub issue number) +- Use `#` only in commit messages, not branch names diff --git a/.ai/skills/code-quality/SKILL.md b/.ai/skills/code-quality/SKILL.md new file mode 100644 index 0000000000..d4df9c0fd3 --- /dev/null +++ b/.ai/skills/code-quality/SKILL.md @@ -0,0 +1,104 @@ +--- +name: code-quality +description: >- + Code-quality standards for RedisInsight: TypeScript strictness, + naming conventions (camelCase, PascalCase, UPPER_SNAKE_CASE), + linting rules, no `any` without reason, no `!important` in styles, + and constant extraction. Use when writing or refactoring any + TypeScript/JavaScript code in this repo, when ESLint or Prettier + issues come up, or when the user mentions code style, lint, naming + conventions, or general code quality. +--- + + +# Code Quality Standards + +## Critical Rules + +- **ALWAYS run linter** after code changes: `yarn lint` +- Linter must pass before committing +- No console.log in production code (use console.warn/error only) + +## TypeScript Standards + +### Essential Rules + +- Use TypeScript for all new code +- **Avoid `any`** - use proper types or `unknown` +- **Prefer interfaces** for object shapes +- Use **type** for unions, intersections, primitives +- Add explicit return types for non-obvious functions +- Leverage type inference where clear + +## Import Organization + +### Required Order (enforced by ESLint) + +1. External libraries (`react`, `lodash`, etc.) +2. Built-in Node modules (`path`, `fs` - backend only) +3. Internal modules with aliases (`uiSrc/*`, `apiClient`) +4. Sibling/parent relative imports +5. Style imports (ALWAYS LAST) + +### Module Aliases + +- `uiSrc/*` → `redisinsight/ui/src/*` (UI workspace) +- `apiClient` → `redisinsight/api-client` (auto-generated OpenAPI types — the UI's only entry point into BE-defined shapes) +- `desktopSrc/*` → `redisinsight/desktop/src/*` (desktop workspace) + +The UI workspace must not import from the backend codebase directly. Use `apiClient` for types and the existing service layer (`uiSrc/services`) for HTTP calls. + +✅ **Use aliases**: `import { Button } from 'uiSrc/components/Button'` +❌ **Avoid relative**: `import { Button } from '../../../ui/src/components/Button'` + +## Naming Conventions + +- **Components**: `PascalCase` - `UserProfile` +- **Functions/Variables**: `camelCase` - `fetchUserProfile` +- **Constants**: `UPPER_SNAKE_CASE` - `MAX_RETRY_ATTEMPTS` +- **Booleans**: Use `is/has/should` prefix - `isLoading`, `hasError` + +## SonarJS Rules + +- Keep cognitive complexity low (refactor complex functions) +- Extract duplicate strings to constants +- Follow DRY principle - no duplicate code +- Use immediate return (avoid unnecessary intermediate variables) + +## Best Practices + +- Use destructuring for objects and arrays +- Use template literals over string concatenation +- Use `const` by default, `let` only when reassignment needed +- Use descriptive variable names +- Handle errors properly +- Clean up subscriptions and timers +- Use constants instead of magic numbers + +## Vite Cache Management + +When updating npm packages (especially `@redis-ui/*` packages): + +1. **Clear Vite cache** after `yarn install`: + + ```bash + rm -rf node_modules/.vite + rm -rf redisinsight/ui/node_modules/.vite + ``` + +2. **Restart dev server** to rebuild dependencies + +3. This ensures new package versions are properly loaded + +## Pre-Commit Checklist + +- [ ] `yarn lint` passes +- [ ] No TypeScript errors +- [ ] Import order is correct +- [ ] No `any` types without reason +- [ ] No console.log statements +- [ ] No magic numbers +- [ ] Descriptive variable names +- [ ] Low cognitive complexity +- [ ] No duplicate code +- [ ] Vite cache cleared (if updated dependencies) diff --git a/.ai/skills/commits/SKILL.md b/.ai/skills/commits/SKILL.md new file mode 100644 index 0000000000..8c0f8b4c30 --- /dev/null +++ b/.ai/skills/commits/SKILL.md @@ -0,0 +1,95 @@ +--- +name: commits +description: >- + Generate commit messages following Conventional Commits format. Use when + creating commits, writing commit messages, or the user asks to commit changes. +--- + +# Commit Message Guidelines + +Follow **Conventional Commits** format: + +``` +(): + + + +