@bonesofspring/ai-rules 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +63 -2
- package/package.json +1 -1
- package/presets/claude/next/CLAUDE.md +11 -0
- package/presets/claude/next/README.md +14 -0
- package/presets/claude/next/agents/README.md +5 -0
- package/presets/claude/next/agents/playwright-test-generator.md +75 -0
- package/presets/claude/next/agents/playwright-test-healer.md +61 -0
- package/presets/claude/next/agents/playwright-test-planner.md +67 -0
- package/presets/claude/next/commands/README.md +4 -2
- package/presets/claude/next/hooks/README.md +5 -0
- package/presets/claude/next/rules/README.md +15 -2
- package/presets/claude/next/rules/api-and-data/README.md +3 -0
- package/presets/claude/next/rules/architecture/README.md +3 -0
- package/presets/claude/next/rules/stack/README.md +3 -0
- package/presets/claude/next/rules/testing/README.md +3 -0
- package/presets/claude/next/rules/tooling-and-review/README.md +3 -0
- package/presets/claude/next/rules/ui-and-accessibility/README.md +3 -0
- package/presets/claude/next/skills/README.md +5 -0
- package/presets/cursor/next/rules/README.md +12 -0
- package/presets/cursor/next/rules/api-services.mdc +56 -0
- package/presets/cursor/next/rules/architecture-boundaries.mdc +47 -0
- package/presets/cursor/next/rules/code-quality-and-refactoring.mdc +44 -0
- package/presets/cursor/next/rules/code-review-mr.mdc +47 -0
- package/presets/cursor/next/rules/emedcard-core.mdc +77 -0
- package/presets/cursor/next/rules/no-props-spread.mdc +39 -0
- package/presets/cursor/next/rules/playwright-agents.mdc +72 -0
- package/presets/cursor/next/rules/react-ui.mdc +67 -0
- package/presets/cursor/next/rules/store-rtk.mdc +59 -0
- package/presets/cursor/next/rules/tests-e2e-structure.mdc +51 -0
- package/presets/cursor/next/rules/tests-unit.mdc +46 -0
- package/presets/cursor/next/rules/next-stack.mdc +0 -9
package/bin/cli.js
CHANGED
|
@@ -17,6 +17,10 @@ const PRESETS = {
|
|
|
17
17
|
rulesDir: '.claude/rules',
|
|
18
18
|
commandsDir: '.claude/commands',
|
|
19
19
|
relBase: ['presets', 'claude'],
|
|
20
|
+
/** Optional dirs under preset root → under `.claude/` (recursive copy). */
|
|
21
|
+
optionalClaudeDirs: ['skills', 'agents', 'hooks'],
|
|
22
|
+
/** Copied from preset root to `.claude/CLAUDE.md` when present. */
|
|
23
|
+
claudeMdSrc: 'CLAUDE.md',
|
|
20
24
|
},
|
|
21
25
|
};
|
|
22
26
|
|
|
@@ -73,6 +77,31 @@ function removeDirIfExists(dir) {
|
|
|
73
77
|
}
|
|
74
78
|
}
|
|
75
79
|
|
|
80
|
+
function removeFileIfExists(filePath) {
|
|
81
|
+
if (fs.existsSync(filePath)) {
|
|
82
|
+
fs.unlinkSync(filePath);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function presetHasAnySource(base, cfg) {
|
|
87
|
+
const rulesSrc = path.join(base, 'rules');
|
|
88
|
+
const commandsSrc = path.join(base, 'commands');
|
|
89
|
+
if (fs.existsSync(rulesSrc) || fs.existsSync(commandsSrc)) {
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
if (cfg.optionalClaudeDirs) {
|
|
93
|
+
for (const name of cfg.optionalClaudeDirs) {
|
|
94
|
+
if (fs.existsSync(path.join(base, name))) {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (cfg.claudeMdSrc && fs.existsSync(path.join(base, cfg.claudeMdSrc))) {
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
|
|
76
105
|
function cmdInit(tool, preset) {
|
|
77
106
|
const cfg = PRESETS[tool];
|
|
78
107
|
if (!cfg) {
|
|
@@ -88,11 +117,21 @@ function cmdInit(tool, preset) {
|
|
|
88
117
|
const commandsSrc = path.join(base, 'commands');
|
|
89
118
|
const cwd = process.cwd();
|
|
90
119
|
|
|
91
|
-
if (!
|
|
120
|
+
if (!presetHasAnySource(base, cfg)) {
|
|
92
121
|
console.error(`Preset "${preset}" for ${tool} not found under ${base}`);
|
|
93
122
|
process.exit(1);
|
|
94
123
|
}
|
|
95
124
|
|
|
125
|
+
if (tool === 'claude' && cfg.claudeMdSrc) {
|
|
126
|
+
const mdFrom = path.join(base, cfg.claudeMdSrc);
|
|
127
|
+
if (fs.existsSync(mdFrom)) {
|
|
128
|
+
const claudeRoot = path.join(cwd, '.claude');
|
|
129
|
+
fs.mkdirSync(claudeRoot, { recursive: true });
|
|
130
|
+
fs.copyFileSync(mdFrom, path.join(claudeRoot, 'CLAUDE.md'));
|
|
131
|
+
console.log('Copied CLAUDE.md → .claude/CLAUDE.md');
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
96
135
|
if (fs.existsSync(rulesSrc)) {
|
|
97
136
|
copyDir(rulesSrc, path.join(cwd, cfg.rulesDir));
|
|
98
137
|
console.log(`Copied rules → ${cfg.rulesDir}`);
|
|
@@ -101,6 +140,16 @@ function cmdInit(tool, preset) {
|
|
|
101
140
|
copyDir(commandsSrc, path.join(cwd, cfg.commandsDir));
|
|
102
141
|
console.log(`Copied commands → ${cfg.commandsDir}`);
|
|
103
142
|
}
|
|
143
|
+
|
|
144
|
+
if (tool === 'claude' && cfg.optionalClaudeDirs) {
|
|
145
|
+
for (const name of cfg.optionalClaudeDirs) {
|
|
146
|
+
const src = path.join(base, name);
|
|
147
|
+
if (fs.existsSync(src)) {
|
|
148
|
+
copyDir(src, path.join(cwd, '.claude', name));
|
|
149
|
+
console.log(`Copied ${name}/ → .claude/${name}/`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
104
153
|
}
|
|
105
154
|
|
|
106
155
|
function cmdClean(tool) {
|
|
@@ -112,7 +161,19 @@ function cmdClean(tool) {
|
|
|
112
161
|
const cwd = process.cwd();
|
|
113
162
|
removeDirIfExists(path.join(cwd, cfg.rulesDir));
|
|
114
163
|
removeDirIfExists(path.join(cwd, cfg.commandsDir));
|
|
115
|
-
|
|
164
|
+
if (tool === 'claude' && cfg.optionalClaudeDirs) {
|
|
165
|
+
for (const name of cfg.optionalClaudeDirs) {
|
|
166
|
+
removeDirIfExists(path.join(cwd, '.claude', name));
|
|
167
|
+
}
|
|
168
|
+
removeFileIfExists(path.join(cwd, '.claude', 'CLAUDE.md'));
|
|
169
|
+
}
|
|
170
|
+
console.log(
|
|
171
|
+
`Removed ${cfg.rulesDir} and ${cfg.commandsDir}` +
|
|
172
|
+
(tool === 'claude' && cfg.optionalClaudeDirs
|
|
173
|
+
? `, optional .claude/{${cfg.optionalClaudeDirs.join(',')}}, and .claude/CLAUDE.md`
|
|
174
|
+
: '') +
|
|
175
|
+
' (if present)',
|
|
176
|
+
);
|
|
116
177
|
}
|
|
117
178
|
|
|
118
179
|
function main() {
|
package/package.json
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Next.js stack — project instructions
|
|
2
|
+
|
|
3
|
+
Краткая точка входа для Claude Code. Подробные правила лежат в модульных файлах под `rules/` (подпапки по темам).
|
|
4
|
+
|
|
5
|
+
See @rules/README.md for how this preset splits instructions.
|
|
6
|
+
|
|
7
|
+
## Conventions
|
|
8
|
+
|
|
9
|
+
- Держите **одну тему на файл**; для больших областей — подпапки в `rules/<topic>/`.
|
|
10
|
+
- Скоуп по путям проекта — через frontmatter `paths:` в отдельных `.md` (см. официальные docs по path-specific rules).
|
|
11
|
+
- Slash-команды — в `commands/`; переиспользуемые сценарии — в `skills/`.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Preset `next` (Claude Code)
|
|
2
|
+
|
|
3
|
+
Структура отличается от пресета Cursor: здесь повторяется типичный **layout проекта Claude Code** под `.claude/`, а не плоский список `.mdc` в `rules/`.
|
|
4
|
+
|
|
5
|
+
| В пресете | Куда копирует `ai-rules init claude --preset next` |
|
|
6
|
+
|-----------|-----------------------------------------------------|
|
|
7
|
+
| `CLAUDE.md` | `.claude/CLAUDE.md` (точка входа, грузится в начале сессии) |
|
|
8
|
+
| `rules/**` | `.claude/rules/**` (рекурсивно: подпапки по темам, см. [документацию](https://code.claude.com/docs/en/memory#organize-rules-with-clauderules)) |
|
|
9
|
+
| `commands/**` | `.claude/commands/**` |
|
|
10
|
+
| `skills/**` | `.claude/skills/**` (если папка есть) |
|
|
11
|
+
| `agents/**` | `.claude/agents/**` (если папка есть) |
|
|
12
|
+
| `hooks/**` | `.claude/hooks/**` (если папка есть) |
|
|
13
|
+
|
|
14
|
+
Файлы правил — обычный Markdown с опциональным YAML frontmatter (`paths:` для скоупа по путям), не формат `.mdc` Cursor.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: playwright-test-generator
|
|
3
|
+
description: 'Use this agent when you need to create automated browser tests using Playwright Examples: <example>Context: User wants to generate a test for the test plan item. <test-suite><!-- Verbatim name of the test spec group w/o ordinal like "Multiplication tests" --></test-suite> <test-name><!-- Name of the test case without the ordinal like "should add two numbers" --></test-name> <test-file><!-- Name of the file to save the test into, like tests/multiplication/should-add-two-numbers.spec.ts --></test-file> <seed-file><!-- Seed file path from test plan --></seed-file> <body><!-- Test case content including steps and expectations --></body></example>'
|
|
4
|
+
tools: Glob, Grep, Read, LS, mcp__playwright-test__browser_click, mcp__playwright-test__browser_drag, mcp__playwright-test__browser_evaluate, mcp__playwright-test__browser_file_upload, mcp__playwright-test__browser_handle_dialog, mcp__playwright-test__browser_hover, mcp__playwright-test__browser_navigate, mcp__playwright-test__browser_press_key, mcp__playwright-test__browser_select_option, mcp__playwright-test__browser_snapshot, mcp__playwright-test__browser_type, mcp__playwright-test__browser_verify_element_visible, mcp__playwright-test__browser_verify_list_visible, mcp__playwright-test__browser_verify_text_visible, mcp__playwright-test__browser_verify_value, mcp__playwright-test__browser_wait_for, mcp__playwright-test__generator_read_log, mcp__playwright-test__generator_setup_page, mcp__playwright-test__generator_write_test
|
|
5
|
+
model: sonnet
|
|
6
|
+
color: blue
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
You are a Playwright Test Generator, an expert in browser automation and end-to-end testing.
|
|
10
|
+
Your specialty is creating robust, reliable Playwright tests that accurately simulate user interactions and validate
|
|
11
|
+
application behavior.
|
|
12
|
+
|
|
13
|
+
## Project-specific test structure (emedcard-web)
|
|
14
|
+
|
|
15
|
+
In this project you MUST respect the existing e2e layout:
|
|
16
|
+
|
|
17
|
+
- Test root: `app/__tests__/e2e`
|
|
18
|
+
- Test plans/specs: `*.cases.md` files under `app/__tests__/e2e/**`
|
|
19
|
+
- Executable tests: `*.spec.ts` files under `app/__tests__/e2e/**`
|
|
20
|
+
- Seed test: `app/__tests__/e2e/seed.spec.ts`
|
|
21
|
+
|
|
22
|
+
When you generate tests:
|
|
23
|
+
|
|
24
|
+
- Use the corresponding `*.cases.md` file under `app/__tests__/e2e/**` as the source plan (for example,
|
|
25
|
+
`app/__tests__/e2e/MedcardRecords/medcard-records.cases.md`).
|
|
26
|
+
- Write or update Playwright test files only under `app/__tests__/e2e/**` (for example,
|
|
27
|
+
`app/__tests__/e2e/MedcardRecords/medcard-records.spec.ts`) instead of creating files in a separate `tests/` folder.
|
|
28
|
+
|
|
29
|
+
# For each test you generate
|
|
30
|
+
- Obtain the test plan with all the steps and verification specification
|
|
31
|
+
- Run the `generator_setup_page` tool to set up page for the scenario
|
|
32
|
+
- For each step and verification in the scenario, do the following:
|
|
33
|
+
- Use Playwright tool to manually execute it in real-time.
|
|
34
|
+
- Use the step description as the intent for each Playwright tool call.
|
|
35
|
+
- Retrieve generator log via `generator_read_log`
|
|
36
|
+
- Immediately after reading the test log, invoke `generator_write_test` with the generated source code
|
|
37
|
+
- File should contain single test
|
|
38
|
+
- File name must be fs-friendly scenario name
|
|
39
|
+
- Test must be placed in a describe matching the top-level test plan item
|
|
40
|
+
- Test title must match the scenario name
|
|
41
|
+
- Includes a comment with the step text before each step execution. Do not duplicate comments if step requires
|
|
42
|
+
multiple actions.
|
|
43
|
+
- Always use best practices from the log when generating tests.
|
|
44
|
+
|
|
45
|
+
<example-generation>
|
|
46
|
+
For following plan:
|
|
47
|
+
|
|
48
|
+
```markdown file=specs/plan.md
|
|
49
|
+
### 1. Adding New Todos
|
|
50
|
+
**Seed:** `tests/seed.spec.ts`
|
|
51
|
+
|
|
52
|
+
#### 1.1 Add Valid Todo
|
|
53
|
+
**Steps:**
|
|
54
|
+
1. Click in the "What needs to be done?" input field
|
|
55
|
+
|
|
56
|
+
#### 1.2 Add Multiple Todos
|
|
57
|
+
...
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Following file is generated:
|
|
61
|
+
|
|
62
|
+
```ts file=add-valid-todo.spec.ts
|
|
63
|
+
// spec: specs/plan.md
|
|
64
|
+
// seed: tests/seed.spec.ts
|
|
65
|
+
|
|
66
|
+
test.describe('Adding New Todos', () => {
|
|
67
|
+
test('Add Valid Todo', async { page } => {
|
|
68
|
+
// 1. Click in the "What needs to be done?" input field
|
|
69
|
+
await page.click(...);
|
|
70
|
+
|
|
71
|
+
...
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
</example-generation>
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: playwright-test-healer
|
|
3
|
+
description: Use this agent when you need to debug and fix failing Playwright tests
|
|
4
|
+
tools: Glob, Grep, Read, LS, Edit, MultiEdit, Write, mcp__playwright-test__browser_console_messages, mcp__playwright-test__browser_evaluate, mcp__playwright-test__browser_generate_locator, mcp__playwright-test__browser_network_requests, mcp__playwright-test__browser_snapshot, mcp__playwright-test__test_debug, mcp__playwright-test__test_list, mcp__playwright-test__test_run
|
|
5
|
+
model: sonnet
|
|
6
|
+
color: red
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
You are the Playwright Test Healer, an expert test automation engineer specializing in debugging and
|
|
10
|
+
resolving Playwright test failures. Your mission is to systematically identify, diagnose, and fix
|
|
11
|
+
broken Playwright tests using a methodical approach.
|
|
12
|
+
|
|
13
|
+
## Project-specific test structure (emedcard-web)
|
|
14
|
+
|
|
15
|
+
In this project you MUST respect the existing e2e layout:
|
|
16
|
+
|
|
17
|
+
- Test root: `app/__tests__/e2e`
|
|
18
|
+
- Test plans/specs: `*.cases.md` files under `app/__tests__/e2e/**`
|
|
19
|
+
- Executable tests: `*.spec.ts` files under `app/__tests__/e2e/**`
|
|
20
|
+
- Seed test: `app/__tests__/e2e/seed.spec.ts`
|
|
21
|
+
|
|
22
|
+
When healing tests:
|
|
23
|
+
|
|
24
|
+
- Only read and modify `*.spec.ts` files under `app/__tests__/e2e/**`.
|
|
25
|
+
- Use the `*.cases.md` file in the same folder as the failing test as the source of truth for intended behavior
|
|
26
|
+
(for example, `app/__tests__/e2e/MedcardRecords/medcard-records.cases.md` for
|
|
27
|
+
`app/__tests__/e2e/MedcardRecords/medcard-records.spec.ts`).
|
|
28
|
+
|
|
29
|
+
Your workflow:
|
|
30
|
+
1. **Initial Execution**: Run all tests using `test_run` tool to identify failing tests
|
|
31
|
+
2. **Debug failed tests**: For each failing test run `test_debug`.
|
|
32
|
+
3. **Error Investigation**: When the test pauses on errors, use available Playwright MCP tools to:
|
|
33
|
+
- Examine the error details
|
|
34
|
+
- Capture page snapshot to understand the context
|
|
35
|
+
- Analyze selectors, timing issues, or assertion failures
|
|
36
|
+
4. **Root Cause Analysis**: Determine the underlying cause of the failure by examining:
|
|
37
|
+
- Element selectors that may have changed
|
|
38
|
+
- Timing and synchronization issues
|
|
39
|
+
- Data dependencies or test environment problems
|
|
40
|
+
- Application changes that broke test assumptions
|
|
41
|
+
5. **Code Remediation**: Edit the test code to address identified issues, focusing on:
|
|
42
|
+
- Updating selectors to match current application state
|
|
43
|
+
- Fixing assertions and expected values
|
|
44
|
+
- Improving test reliability and maintainability
|
|
45
|
+
- For inherently dynamic data, utilize regular expressions to produce resilient locators
|
|
46
|
+
6. **Verification**: Restart the test after each fix to validate the changes
|
|
47
|
+
7. **Iteration**: Repeat the investigation and fixing process until the test passes cleanly
|
|
48
|
+
|
|
49
|
+
Key principles:
|
|
50
|
+
- Be systematic and thorough in your debugging approach
|
|
51
|
+
- Document your findings and reasoning for each fix
|
|
52
|
+
- Prefer robust, maintainable solutions over quick hacks
|
|
53
|
+
- Use Playwright best practices for reliable test automation
|
|
54
|
+
- If multiple errors exist, fix them one at a time and retest
|
|
55
|
+
- Provide clear explanations of what was broken and how you fixed it
|
|
56
|
+
- You will continue this process until the test runs successfully without any failures or errors.
|
|
57
|
+
- If the error persists and you have high level of confidence that the test is correct, mark this test as test.fixme()
|
|
58
|
+
so that it is skipped during the execution. Add a comment before the failing step explaining what is happening instead
|
|
59
|
+
of the expected behavior.
|
|
60
|
+
- Do not ask user questions, you are not interactive tool, do the most reasonable thing possible to pass the test.
|
|
61
|
+
- Never wait for networkidle or use other discouraged or deprecated apis
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: playwright-test-planner
|
|
3
|
+
description: Use this agent when you need to create comprehensive test plan for a web application or website
|
|
4
|
+
tools: Glob, Grep, Read, LS, mcp__playwright-test__browser_click, mcp__playwright-test__browser_close, mcp__playwright-test__browser_console_messages, mcp__playwright-test__browser_drag, mcp__playwright-test__browser_evaluate, mcp__playwright-test__browser_file_upload, mcp__playwright-test__browser_handle_dialog, mcp__playwright-test__browser_hover, mcp__playwright-test__browser_navigate, mcp__playwright-test__browser_navigate_back, mcp__playwright-test__browser_network_requests, mcp__playwright-test__browser_press_key, mcp__playwright-test__browser_run_code, mcp__playwright-test__browser_select_option, mcp__playwright-test__browser_snapshot, mcp__playwright-test__browser_take_screenshot, mcp__playwright-test__browser_type, mcp__playwright-test__browser_wait_for, mcp__playwright-test__planner_setup_page, mcp__playwright-test__planner_save_plan
|
|
5
|
+
model: sonnet
|
|
6
|
+
color: green
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
You are an expert web test planner with extensive experience in quality assurance, user experience testing, and test
|
|
10
|
+
scenario design. Your expertise includes functional testing, edge case identification, and comprehensive test coverage
|
|
11
|
+
planning.
|
|
12
|
+
|
|
13
|
+
## Project-specific test structure (emedcard-web)
|
|
14
|
+
|
|
15
|
+
In this project you MUST respect the existing e2e layout:
|
|
16
|
+
|
|
17
|
+
- Test root: `app/__tests__/e2e`
|
|
18
|
+
- Test plans/specs: `*.cases.md` files under `app/__tests__/e2e/**`
|
|
19
|
+
- Executable tests: `*.spec.ts` files under `app/__tests__/e2e/**`
|
|
20
|
+
- Seed test: `app/__tests__/e2e/seed.spec.ts`
|
|
21
|
+
|
|
22
|
+
When you create or update a test plan:
|
|
23
|
+
|
|
24
|
+
- Use the appropriate `*.cases.md` file under `app/__tests__/e2e/**` (for example,
|
|
25
|
+
`app/__tests__/e2e/MedcardRecords/medcard-records.cases.md`) instead of creating files in a separate `specs/` folder.
|
|
26
|
+
- Treat these `*.cases.md` files as the canonical, human-readable test plans for the Generator and Healer agents.
|
|
27
|
+
|
|
28
|
+
You will:
|
|
29
|
+
|
|
30
|
+
1. **Navigate and Explore**
|
|
31
|
+
- Invoke the `planner_setup_page` tool once to set up page before using any other tools
|
|
32
|
+
- Explore the browser snapshot
|
|
33
|
+
- Do not take screenshots unless absolutely necessary
|
|
34
|
+
- Use `browser_*` tools to navigate and discover interface
|
|
35
|
+
- Thoroughly explore the interface, identifying all interactive elements, forms, navigation paths, and functionality
|
|
36
|
+
|
|
37
|
+
2. **Analyze User Flows**
|
|
38
|
+
- Map out the primary user journeys and identify critical paths through the application
|
|
39
|
+
- Consider different user types and their typical behaviors
|
|
40
|
+
|
|
41
|
+
3. **Design Comprehensive Scenarios**
|
|
42
|
+
|
|
43
|
+
Create detailed test scenarios that cover:
|
|
44
|
+
- Happy path scenarios (normal user behavior)
|
|
45
|
+
- Edge cases and boundary conditions
|
|
46
|
+
- Error handling and validation
|
|
47
|
+
|
|
48
|
+
4. **Structure Test Plans**
|
|
49
|
+
|
|
50
|
+
Each scenario must include:
|
|
51
|
+
- Clear, descriptive title
|
|
52
|
+
- Detailed step-by-step instructions
|
|
53
|
+
- Expected outcomes where appropriate
|
|
54
|
+
- Assumptions about starting state (always assume blank/fresh state)
|
|
55
|
+
- Success criteria and failure conditions
|
|
56
|
+
|
|
57
|
+
5. **Create Documentation**
|
|
58
|
+
|
|
59
|
+
Submit your test plan using `planner_save_plan` tool.
|
|
60
|
+
|
|
61
|
+
**Quality Standards**:
|
|
62
|
+
- Write steps that are specific enough for any tester to follow
|
|
63
|
+
- Include negative testing scenarios
|
|
64
|
+
- Ensure scenarios are independent and can be run in any order
|
|
65
|
+
|
|
66
|
+
**Output Format**: Always save the complete test plan as a markdown file with clear headings, numbered steps, and
|
|
67
|
+
professional formatting suitable for sharing with development and QA teams.
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `.claude/commands` (preset next)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Определения slash-команд для проекта. Копируются в `.claude/commands/` при `ai-rules init claude --preset next`.
|
|
4
|
+
|
|
5
|
+
См. также корневой `README.md` пресета — у Claude Code помимо `rules/` и `commands/` часто используются `skills/`, `agents/`, `hooks/`.
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `.claude/rules` (preset next)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
В Claude Code все `.md` под `rules/` **обнаруживаются рекурсивно** — подпапки по темам уместнее, чем один длинный файл.
|
|
4
|
+
|
|
5
|
+
Соответствие темам из пресета Cursor (для переноса смысла из `.mdc`):
|
|
6
|
+
|
|
7
|
+
| Папка | О чём |
|
|
8
|
+
|-------|--------|
|
|
9
|
+
| `stack/` | Next.js, React, TypeScript |
|
|
10
|
+
| `architecture/` | границы слоёв, модули |
|
|
11
|
+
| `api-and-data/` | сервисы, API, данные |
|
|
12
|
+
| `testing/` | unit, e2e, Playwright |
|
|
13
|
+
| `ui-and-accessibility/` | UI, a11y, без spread props там, где это правило команды |
|
|
14
|
+
| `tooling-and-review/` | качество кода, ревью MR |
|
|
15
|
+
|
|
16
|
+
Добавляйте сюда `.md` файлы с осмысленными именами (`testing.md`, `api-design.md`, …).
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# `.claude/skills` (preset next)
|
|
2
|
+
|
|
3
|
+
[Skills](https://code.claude.com/docs/en/skills) в Claude Code — сценарии, которые подгружаются по необходимости, а не в каждой сессии целиком. Добавьте сюда `SKILL.md` или структуру skills по документации инструмента.
|
|
4
|
+
|
|
5
|
+
Папка копируется в `.claude/skills/` при `ai-rules init claude --preset next`, если существует.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
### Разница .mdc и .md в .cursor/rules
|
|
2
|
+
|
|
3
|
+
#### .md
|
|
4
|
+
Обычный markdown‑файл. Cursor видит его как документацию/контент, но не как правило, которое нужно автоматически применять.
|
|
5
|
+
|
|
6
|
+
#### .mdc
|
|
7
|
+
Специальный формат Cursor Rule:
|
|
8
|
+
- сверху обязателен YAML‑frontmatter с полями вроде description, globs, alwaysApply;
|
|
9
|
+
- файл лежит в .cursor/rules/;
|
|
10
|
+
- Cursor интерпретирует его как конфигурацию поведения ассистента для этого репо (автоматически подмешивает содержимое в контекст, когда правило подходит).
|
|
11
|
+
|
|
12
|
+
- То есть .mdc = “markdown + config для Cursor”, .md = просто текст без управляющего смысла для ассистента.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Конвенции API сервисов и мапперов Medcard
|
|
3
|
+
globs: src/api/services/**/*.ts
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Роль API слоя
|
|
8
|
+
|
|
9
|
+
- Инкапсулировать всё, что связано с:
|
|
10
|
+
- HTTP/axios запросами,
|
|
11
|
+
- URL/путями,
|
|
12
|
+
- заголовками и кодами ответов,
|
|
13
|
+
- DTO backend.
|
|
14
|
+
- Предоставлять UI и store **стабильный доменный интерфейс**:
|
|
15
|
+
- функции, работающие с доменными типами из `@/types/**`.
|
|
16
|
+
- мапперы между DTO и доменными типами.
|
|
17
|
+
|
|
18
|
+
# Структура модулей
|
|
19
|
+
|
|
20
|
+
- Для каждой доменной области (Medcard, OfflineConsultation, RequestForAnalysis и т.п.):
|
|
21
|
+
- отдельный каталог в `src/api/services/MedcardApiService/**`.
|
|
22
|
+
- Внутри модуля:
|
|
23
|
+
- файлы с вызовами API (`index.ts` или `*.service.ts`);
|
|
24
|
+
- файлы мапперов (`*responseMappers.ts`);
|
|
25
|
+
- специфичные типы запросов/ответов (если не вынесены в `@/types/**`).
|
|
26
|
+
- один или несколько **public API** файлов (`index.ts` или barrel‑файлы), через которые к модулю обращаются UI, store и другие слои.
|
|
27
|
+
|
|
28
|
+
# Мапперы и типы
|
|
29
|
+
|
|
30
|
+
- Для каждого запроса/эндпоинта:
|
|
31
|
+
- описывать **response‑тип (DTO)**, точно соответствующий контракту backend;
|
|
32
|
+
- определять **целевой доменный тип** в `src/types/**`, с которым будет работать приложение (включая вычисляемые/агрегированные поля).
|
|
33
|
+
- Мапперы (например, `*responseMappers.ts`):
|
|
34
|
+
- чистые функции, без сайд‑эффектов;
|
|
35
|
+
- выполняют все необходимые вычисления и преобразования данных (булевы флаги, склейка строк, агрегаты и т.п.) при переводе из DTO в доменные модели;
|
|
36
|
+
- при необходимости обеспечивают обратное преобразование (доменные модели -> транспортные типы).
|
|
37
|
+
- UI и store работают только с доменными типами (из `@/types/**` или экспортируемыми из API слоя), а не с "сырыми" DTO.
|
|
38
|
+
|
|
39
|
+
# Обработка ошибок
|
|
40
|
+
|
|
41
|
+
- API‑слой:
|
|
42
|
+
- не должен "глотать" ошибки без следа;
|
|
43
|
+
- либо бросает доменные/унифицированные ошибки;
|
|
44
|
+
- либо возвращает результат в `Result<T, E>`‑подобной форме (если такой паттерн принят в проекте).
|
|
45
|
+
- Интеграция с Sentry / OpenTelemetry:
|
|
46
|
+
- если используется — делать её централизованно (например, в HTTP‑клиенте или обёртках), а не в каждом методе.
|
|
47
|
+
|
|
48
|
+
# Требование к агенту
|
|
49
|
+
|
|
50
|
+
При добавлении/изменении API‑метода:
|
|
51
|
+
- Следовать существующим сервисам и мапперам как эталону.
|
|
52
|
+
- Не смешивать слой API и UI/store:
|
|
53
|
+
- компоненты не должны зависеть от DTO;
|
|
54
|
+
- store не должен знать о HTTP‑деталях (URL, коды).
|
|
55
|
+
- При использовании API‑сервисов в UI, store и утилитах импортировать только из public API файлов модуля (например, `@/api/services/MedcardApiService/.../index`), а не из внутренних файлов‑реализаций.
|
|
56
|
+
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Архитектурные границы и правила импортов
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Границы между слоями
|
|
7
|
+
|
|
8
|
+
- **UI (src/ui/**)**:
|
|
9
|
+
- Может импортировать: `@/ui/**`, `@/store/**`, `@/types/**`, `@/api/services/**` (через публичные интерфейсы).
|
|
10
|
+
- Не должен:
|
|
11
|
+
- обращаться к HTTP/axios напрямую;
|
|
12
|
+
- знать детали DTO backend — только доменные типы.
|
|
13
|
+
- **Store (src/store/**)**:
|
|
14
|
+
- Может импортировать: `@/store/**`, `@/api/services/**`, `@/types/**`.
|
|
15
|
+
- Не должен:
|
|
16
|
+
- зависеть от конкретных UI‑компонентов;
|
|
17
|
+
- напрямую работать с global/window API.
|
|
18
|
+
- **API (src/api/services/**)**:
|
|
19
|
+
- Может импортировать: `@/types/**`, общие утилиты.
|
|
20
|
+
- Не должен:
|
|
21
|
+
- тянуть в себя UI или store;
|
|
22
|
+
- смешивать HTTP‑слой и доменный слой — использовать мапперы.
|
|
23
|
+
|
|
24
|
+
# Правила импортов
|
|
25
|
+
|
|
26
|
+
- Всегда использовать алиас `@/...` для импортов между слоями.
|
|
27
|
+
- Внутри одного модуля/фичи можно использовать относительные импорты, но **без подъёма выше корня фичи** (избегать `../../../`).
|
|
28
|
+
- При обращении из компонентов, хуков, утилит и других модулей к чужому слою или фиче использовать только **public API** (barrel/index‑файлы и явно экспортируемые сущности), не делать deep‑импорты внутренних файлов других фич.
|
|
29
|
+
- При добавлении нового кода проверять:
|
|
30
|
+
- если модуль переиспользуемый — он должен зависеть только от более "низких" слоёв (types, utils, api), но не от страниц.
|
|
31
|
+
|
|
32
|
+
# Организация фич
|
|
33
|
+
|
|
34
|
+
- Для сложных фич (например, OfflineConsultation):
|
|
35
|
+
- Страница: `src/ui/pages/OfflineConsultationPage/**`.
|
|
36
|
+
- Локальные компоненты: поддиректории `components/**` внутри страницы.
|
|
37
|
+
- Связанный store: `src/store/slices/OfflineConsultation/**`.
|
|
38
|
+
- API: `src/api/services/MedcardApiService/OfflineConsultation/**`.
|
|
39
|
+
- Типы: `src/types/OfflineConsultation.types.ts` или аналогичный файл.
|
|
40
|
+
|
|
41
|
+
# Требование к агенту
|
|
42
|
+
|
|
43
|
+
При добавлении новой функциональности:
|
|
44
|
+
- Разместить файлы в **соответствующих слоях**.
|
|
45
|
+
- Проверить существующие фичи с аналогичной структурой и **повторить их организацию**.
|
|
46
|
+
- Не "коротить" слои (например, не вызывать API прямо из компонента только ради упрощения).
|
|
47
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Поддержка и улучшение качества кода и архитектуры
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Поддержка существующего стиля
|
|
7
|
+
|
|
8
|
+
- Новые изменения должны:
|
|
9
|
+
- следовать существующим паттернам (имена, структура, типизация);
|
|
10
|
+
- минимизировать "стилистический шум" (лишние правки форматирования, rename без нужды).
|
|
11
|
+
- Перед добавлением нового решения:
|
|
12
|
+
- искать аналогичное в коде и **повторять подход**, а не изобретать новый.
|
|
13
|
+
- проверять, нет ли уже подходящего компонента или паттерна в `@sds/*` или существующем UI‑коде, прежде чем добавлять новый кастомный контрол.
|
|
14
|
+
- использовать при обращении к чужим модулям только их **public API** (index/barrel‑файлы и явно экспортируемые сущности), а deep‑импорты внутренних файлов рассматривать как повод для рефакторинга.
|
|
15
|
+
|
|
16
|
+
# Рефакторинг при изменениях
|
|
17
|
+
|
|
18
|
+
- Разрешён лёгкий refactor, если он:
|
|
19
|
+
- уменьшает дублирование;
|
|
20
|
+
- повышает читаемость;
|
|
21
|
+
- не ломает публичные контракты модулей.
|
|
22
|
+
- Примеры допустимых улучшений:
|
|
23
|
+
- вынести дублирующуюся логику в общий хук/утилиту;
|
|
24
|
+
- типизировать `any` и `unknown`, если это безболезненно;
|
|
25
|
+
- разделить слишком крупный компонент на несколько более простых;
|
|
26
|
+
- заменить локальные «магические» CSS‑значения (цвета, отступы, размеры) на токены из `@sds/tokens-*`, `@sds/brand-colors`, `@sds/tokens-typography` или централизованные UI‑примитивы;
|
|
27
|
+
- заменить deep‑импорты внутренних файлов других модулей на обращения к их public API.
|
|
28
|
+
|
|
29
|
+
# Ограничения
|
|
30
|
+
|
|
31
|
+
- Не выполнять "большой" рефакторинг, если задача точечная и не про архитектуру:
|
|
32
|
+
- не менять структуру директорий;
|
|
33
|
+
- не менять названия публичных типов/функций без явного запроса.
|
|
34
|
+
- При необходимости крупного изменения:
|
|
35
|
+
- сначала локально улучшить архитектуру минимальными шагами;
|
|
36
|
+
- оставить код в консистентном состоянии.
|
|
37
|
+
|
|
38
|
+
# Требование к агенту
|
|
39
|
+
|
|
40
|
+
При каждом изменении:
|
|
41
|
+
- Поддерживать принцип **“boy scout rule”**:
|
|
42
|
+
- оставлять модуль в немного лучшем состоянии, чем до изменения (простые, безопасные улучшения).
|
|
43
|
+
- Не жертвовать архитектурой и слоями ради краткости реализации.
|
|
44
|
+
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Требования к code review агентами Cursor для GitLab merge requests в emedcard-web
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Code review merge requests
|
|
7
|
+
|
|
8
|
+
- **Когда применять**
|
|
9
|
+
- Если пользователь просит: "проведи ревью", "оценить MR/ветку/дифф", "посмотри изменения".
|
|
10
|
+
- Опираться на локальный репозиторий: текущую ветку, `git diff` и открытые файлы, а не на данные GitLab API.
|
|
11
|
+
|
|
12
|
+
- **Что обязан проверить агент**
|
|
13
|
+
- **Архитектура и слои**:
|
|
14
|
+
- Соблюдение правил из `architecture-boundaries.mdc` и `emedcard-core.mdc`:
|
|
15
|
+
- UI (`src/ui/**`) не ходит напрямую в HTTP/axios и не знает DTO.
|
|
16
|
+
- Store (`src/store/**`) не зависит от UI и не работает с "сырыми" HTTP.
|
|
17
|
+
- API (`src/api/services/**`) не тянет UI/store, использует мапперы.
|
|
18
|
+
- **Импорты и организация кода**:
|
|
19
|
+
- Использование алиаса `@/...` вместо относительных импортов выше по дереву.
|
|
20
|
+
- Отсутствие deep‑импортов во внешние фичи; использование только public API.
|
|
21
|
+
- Размещение новых файлов в корректных слоях и директориях фич.
|
|
22
|
+
- **Типы и TS‑строгость**:
|
|
23
|
+
- Не допускать новых `any`; предпочитать доменные типы из `src/types/**`.
|
|
24
|
+
- Проверять корректность пропсов/возвращаемых типов, особенно в UI и API‑слое.
|
|
25
|
+
- **UI, стили и SDS**:
|
|
26
|
+
- Для компонентов и стилей сверяться с `react-ui.mdc` и `emedcard-core.mdc`:
|
|
27
|
+
- Использовать Linaria и компоненты/токены `@sds/*`, а не "магические" значения.
|
|
28
|
+
- Сохранять консистентность с существующими компонентами и паттернами.
|
|
29
|
+
- **Тесты**:
|
|
30
|
+
- Проверять, что для нетривиальных изменений:
|
|
31
|
+
- либо обновлены/добавлены unit‑тесты (`tests-unit.mdc`),
|
|
32
|
+
- либо e2e‑сценарии/спеки отражают новую логику (`playwright-agents.mdc`, `tests-e2e-structure.mdc`).
|
|
33
|
+
- Указывать, какие именно тесты стоит добавить или поправить.
|
|
34
|
+
|
|
35
|
+
- **Глубина и формат ревью**
|
|
36
|
+
- Фокус на **изменениях MR** (дифф относительно целевой ветки), а не на всём проекте.
|
|
37
|
+
- Сначала дать **высокоуровневый обзор** (что делает MR, риски, архитектурные замечания), затем список конкретных комментариев.
|
|
38
|
+
- Каждый комментарий делать:
|
|
39
|
+
- **конкретным** (указать файл/участок и проблему),
|
|
40
|
+
- **практичным** (предложить вариант исправления, опираясь на существующие паттерны),
|
|
41
|
+
- без "больших рефакторингов" в духе `code-quality-and-refactoring.mdc`, если задача локальная.
|
|
42
|
+
|
|
43
|
+
- **Ограничения для агента**
|
|
44
|
+
- Не придумывать несуществующие GitLab сущности (лейблы, авторов, статусы пайплайнов).
|
|
45
|
+
- Не менять общую архитектуру фичи без прямого запроса пользователя.
|
|
46
|
+
- Следовать принципу "boy scout rule": предлагать улучшения, которые реально можно внести в рамках MR.
|
|
47
|
+
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Базовые принципы, стек и архитектура emedcard-web
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Стек и окружение
|
|
7
|
+
|
|
8
|
+
- Проект: **Next.js 16**, **React 19**, **TypeScript 5 (strict)**.
|
|
9
|
+
- Сборка: Webpack/Rspack, Node >= 24.
|
|
10
|
+
- Тесты: Jest + Testing Library, e2e — Playwright.
|
|
11
|
+
- Моки: **MSW** (`msw`, `public/mockServiceWorker.js`).
|
|
12
|
+
- Стили и UI:
|
|
13
|
+
- CSS-in-JS: **Linaria** (`@linaria/core`, `@linaria/react`).
|
|
14
|
+
- Дизайн‑система: **SDS** (`@sds/*`) и набор дизайн‑токенов (`@sds/tokens-*`, `@sds/brand-colors`, `@sds/tokens-typography`).
|
|
15
|
+
- Трассировка и мониторинг: Sentry, OpenTelemetry.
|
|
16
|
+
|
|
17
|
+
# Структура проекта (верхний уровень)
|
|
18
|
+
|
|
19
|
+
- `app/` — корень Next.js приложения.
|
|
20
|
+
- `app/src/**` — исходный код приложения.
|
|
21
|
+
- `app/__tests__/e2e/**` — e2e‑тесты и планы.
|
|
22
|
+
- `app/tsconfig.json`:
|
|
23
|
+
- `baseUrl: "."`
|
|
24
|
+
- `paths: { "@/*": ["./src/*"] }`
|
|
25
|
+
|
|
26
|
+
**Требование:** во всех новых изменениях использовать алиас `@/*` вместо относительных импортов выше по дереву.
|
|
27
|
+
|
|
28
|
+
# Архитектурные слои
|
|
29
|
+
|
|
30
|
+
- **UI слой** (`src/ui/**`):
|
|
31
|
+
- `src/ui/pages/**` — страницы и контейнеры.
|
|
32
|
+
- `src/ui/components/**` — переиспользуемые компоненты.
|
|
33
|
+
- **Store слой** (`src/store/**`):
|
|
34
|
+
- `src/store/slices/**` — Redux Toolkit слайсы.
|
|
35
|
+
- `src/store/middleware/**` — middleware для сайд‑эффектов (например, файлы, аналитика).
|
|
36
|
+
- **API слой** (`src/api/services/**`):
|
|
37
|
+
- Сервисы и мапперы, инкапсулирующие HTTP‑логику.
|
|
38
|
+
- **Типы** (`src/types/**`):
|
|
39
|
+
- Общие доменные типы (OfflineConsultation, Medcard, Conclusion и т.д.).
|
|
40
|
+
- **Моки и тестовые данные** (`src/mocks/**`):
|
|
41
|
+
- Моковые данные и обработчики для MSW.
|
|
42
|
+
|
|
43
|
+
# Общие архитектурные принципы
|
|
44
|
+
|
|
45
|
+
- **Чёткое разделение слоёв**:
|
|
46
|
+
- UI знает только о доменных типах и публичных интерфейсах store/API.
|
|
47
|
+
- Store знает о доменных типах и API‑сервисах.
|
|
48
|
+
- API знает о транспортном слое (HTTP, axios и пр.) и DTO.
|
|
49
|
+
- **Никаких "проникновений" слоёв**:
|
|
50
|
+
- UI не обращается к API напрямую — только через store или абстракции сервисов.
|
|
51
|
+
- Store не работает напрямую с "сырыми" HTTP‑ответами — только через мапперы.
|
|
52
|
+
- **Типы — источник правды**:
|
|
53
|
+
- Новые сущности описывать в `src/types/**`, переиспользовать, а не дублировать типы по слоям.
|
|
54
|
+
- Не использовать `any`; при необходимости — `unknown` + безопасное сужение типа.
|
|
55
|
+
|
|
56
|
+
# Кодстайл и качества кода
|
|
57
|
+
|
|
58
|
+
- Следовать конфигам `eslint.config.mjs`, `.prettierrc`, `.stylelintrc`.
|
|
59
|
+
- Поддерживать:
|
|
60
|
+
- KISS, DRY, SOLID (в разумных пределах для фронта).
|
|
61
|
+
- Модульность и переиспользование через компоненты, хуки, слайсы, сервисы.
|
|
62
|
+
- Консистентный визуальный стиль за счёт использования готовых компонентов `@sds/*` и дизайн‑токенов @sds вместо локальных "магических" значений.
|
|
63
|
+
- При добавлении нового кода **искать и копировать существующие паттерны**:
|
|
64
|
+
- Для страниц — аналогичные файлы в `src/ui/pages/**`.
|
|
65
|
+
- Для блоков — компоненты в `src/ui/components/**`.
|
|
66
|
+
- Для API — сервисы в `src/api/services/**`.
|
|
67
|
+
- Для состояния — слайсы в `src/store/slices/**`.
|
|
68
|
+
|
|
69
|
+
# Работа агента
|
|
70
|
+
|
|
71
|
+
При генерации кода:
|
|
72
|
+
- Определить целевой слой (UI/store/API/типизация/тесты).
|
|
73
|
+
- Найти в соответствующей директории похожие примеры и **копировать архитектурный паттерн** (структура файлов, типы, именование).
|
|
74
|
+
- Не упрощать архитектуру в ущерб существующим слоям (не тянуть API в UI, не описывать "DTO" прямо в компонентах).
|
|
75
|
+
- Избегать использования `any` при типизации кода; при необходимости использовать `unknown` с последующим безопасным сужением типов.
|
|
76
|
+
- После создания или редактирования любых файлов **обязательно проверять проект на ошибки TypeScript и ESLint** (либо точечно по изменённым файлам, либо по всему проекту) и устранять найденные проблемы, если это возможно без изменения бизнес‑логики.
|
|
77
|
+
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Избегать спред-а пропов при передаче в компоненты
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Не использовать спред пропов при передаче в компоненты
|
|
7
|
+
|
|
8
|
+
При вызове React-компонентов **передавать пропы явно**, а не через spread (`{...props}`).
|
|
9
|
+
|
|
10
|
+
## Почему
|
|
11
|
+
|
|
12
|
+
- Явная передача делает зависимости компонента очевидными при чтении кода.
|
|
13
|
+
- Упрощает рефакторинг и поиск использований.
|
|
14
|
+
- Снижает риск случайно пробросить лишние или устаревшие пропы.
|
|
15
|
+
|
|
16
|
+
## Примеры
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
// ❌ Плохо
|
|
20
|
+
const commonProps = { a, b, c }
|
|
21
|
+
return <Child {...commonProps} />
|
|
22
|
+
|
|
23
|
+
// ❌ Плохо
|
|
24
|
+
return <Child {...props} />
|
|
25
|
+
|
|
26
|
+
// ✅ Хорошо
|
|
27
|
+
return (
|
|
28
|
+
<Child
|
|
29
|
+
a={a}
|
|
30
|
+
b={b}
|
|
31
|
+
c={c}
|
|
32
|
+
/>
|
|
33
|
+
)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Исключения
|
|
37
|
+
|
|
38
|
+
- Передача всех пропов в нативный DOM-элемент (`<div {...rest} />`) допустима, если `rest` содержит только валидные HTML-атрибуты.
|
|
39
|
+
- Делегирование пропов в обёртку (wrapper) допустимо, если это явно документировано и обосновано.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Playwright Agents (planner/generator/healer) configuration for e2e structure in app/__tests__/e2e
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Playwright Agents in this project
|
|
7
|
+
|
|
8
|
+
In this repository, Playwright Agents (planner, generator, healer) **must follow the existing e2e structure**:
|
|
9
|
+
|
|
10
|
+
- **Test directory**: `app/__tests__/e2e`
|
|
11
|
+
- **Test plans (specs)**: `*.cases.md` files under `app/__tests__/e2e/**`
|
|
12
|
+
- **Executable tests**: `*.spec.ts` files under `app/__tests__/e2e/**`
|
|
13
|
+
- **Seed test**: `app/__tests__/e2e/seed.spec.ts`
|
|
14
|
+
|
|
15
|
+
Do **not** introduce separate top-level `specs/` and `tests/` folders for real test coverage. Those may be used only as temporary sandboxes if explicitly requested.
|
|
16
|
+
|
|
17
|
+
## Planner (test plans)
|
|
18
|
+
|
|
19
|
+
When acting as a **Planner** (or working with the Playwright planner agent):
|
|
20
|
+
|
|
21
|
+
- **Treat `*.cases.md` as the canonical test plan files**, equivalent to Playwright's `specs/*.md`.
|
|
22
|
+
- **Location**:
|
|
23
|
+
- For a feature/domain, use the corresponding `*.cases.md` file under `app/__tests__/e2e`, e.g.:
|
|
24
|
+
- `app/__tests__/e2e/MedcardRecords/medcard-records.cases.md`
|
|
25
|
+
- `app/__tests__/e2e/RequestForAnalysis/schedule-display.cases.md`
|
|
26
|
+
- **Content requirements**:
|
|
27
|
+
- Group scenarios by feature and subfeature using headings.
|
|
28
|
+
- For each scenario include:
|
|
29
|
+
- clear title,
|
|
30
|
+
- preconditions,
|
|
31
|
+
- ordered steps,
|
|
32
|
+
- expected results.
|
|
33
|
+
- Write in concise business language, but precise enough for automatic test generation.
|
|
34
|
+
- **Seed**:
|
|
35
|
+
- Assume environment is prepared by `app/__tests__/e2e/seed.spec.ts` (login, baseURL, mocks, etc.).
|
|
36
|
+
|
|
37
|
+
When asked to "generate a test plan" for a feature, **create or update the appropriate `*.cases.md` file in `app/__tests__/e2e/**`**, not in a separate `specs/` folder.
|
|
38
|
+
|
|
39
|
+
## Generator (tests from plans)
|
|
40
|
+
|
|
41
|
+
When acting as a **Generator** (or working with the Playwright generator agent):
|
|
42
|
+
|
|
43
|
+
- **Source of truth for scenarios**:
|
|
44
|
+
- Use the relevant `*.cases.md` file under `app/__tests__/e2e/**` as the test plan.
|
|
45
|
+
- **Target for tests**:
|
|
46
|
+
- Generate or update `*.spec.ts` files under the same folder, e.g.:
|
|
47
|
+
- plan: `app/__tests__/e2e/MedcardRecords/medcard-records.cases.md`
|
|
48
|
+
- tests: `app/__tests__/e2e/MedcardRecords/medcard-records.spec.ts` (or additional `*.spec.ts` in that folder if needed).
|
|
49
|
+
- **Structure**:
|
|
50
|
+
- Use `test.describe` to group by top-level plan sections (feature / user flow).
|
|
51
|
+
- Use `test(...)` titles that match scenario names from the plan.
|
|
52
|
+
- Prefer Page Object and fluent interfaces that already exist in this project, for example:
|
|
53
|
+
- `app/__tests__/e2e/MedcardRecords/MedcardRecordsPage.ts`
|
|
54
|
+
- shared helpers under `app/__tests__/e2e/_shared/`.
|
|
55
|
+
- **Seed**:
|
|
56
|
+
- If a seed test is needed, use `app/__tests__/e2e/seed.spec.ts` as the reference for environment setup.
|
|
57
|
+
|
|
58
|
+
Do **not** generate Playwright tests into a separate `tests/` folder by default. Keep all e2e tests under `app/__tests__/e2e/**` to respect project conventions.
|
|
59
|
+
|
|
60
|
+
## Healer (fixing tests)
|
|
61
|
+
|
|
62
|
+
When acting as a **Healer** (or working with the Playwright healer agent):
|
|
63
|
+
|
|
64
|
+
- Operate only on `*.spec.ts` files under `app/__tests__/e2e/**`.
|
|
65
|
+
- Use `*.cases.md` in the same folder as **documentation of the intended behavior**:
|
|
66
|
+
- Do not weaken or change business assertions in tests in a way that conflicts with the corresponding `*.cases.md`.
|
|
67
|
+
- Prefer updating locators, waits, and flow details to match the UI while keeping the scenario semantics intact.
|
|
68
|
+
- When multiple specs are involved, prioritize:
|
|
69
|
+
- the spec file in the same folder as the failing test,
|
|
70
|
+
- then shared utilities in `app/__tests__/e2e/_shared/`.
|
|
71
|
+
|
|
72
|
+
Healer should keep tests aligned with the existing test plans (`*.cases.md`) and with the page objects and helpers already used in the project.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Паттерны React/Next UI и Linaria в emedcard-web
|
|
3
|
+
globs: src/ui/**/*.tsx
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Общие правила компонентов
|
|
8
|
+
|
|
9
|
+
- Использовать **функциональные компоненты** с хуками, без классов.
|
|
10
|
+
- Компонент должен:
|
|
11
|
+
- быть максимально "тонким" по бизнес‑логике;
|
|
12
|
+
- делегировать состояние в store/хуки, если оно нужно в нескольких местах;
|
|
13
|
+
- использовать SDS‑компоненты как строительные блоки.
|
|
14
|
+
- Перед созданием нового UI‑контрола агент должен явно рассмотреть существующие компоненты `@sds/*` и, если есть близкий по назначению, переиспользовать или расширить его вместо написания кастомного с нуля.
|
|
15
|
+
- Для повторяемой логики создавать `useSomething`‑хуки рядом или в `src/ui/hooks/**`.
|
|
16
|
+
- При обращении к store, API, общим хелперам и утилитам компоненты и хуки должны использовать только их **public API** (например, `@/store`, `@/store/slices/Foo`, `@/lib/utils`), а не импортировать внутренние файлы реализации других модулей.
|
|
17
|
+
|
|
18
|
+
# Структура файлов
|
|
19
|
+
|
|
20
|
+
Для страницы/крупного блока:
|
|
21
|
+
- `FeatureBlock.tsx` — JSX и композиция.
|
|
22
|
+
- `styles.ts` — Linaria‑стили (`styled`, `css`).
|
|
23
|
+
- `index.ts` — реэкспорт (если нужно наружу).
|
|
24
|
+
|
|
25
|
+
Для переиспользуемого компонента:
|
|
26
|
+
- Папка с именем компонента:
|
|
27
|
+
- `ComponentName.tsx`
|
|
28
|
+
- `styles.ts`
|
|
29
|
+
- опционально: `types.ts`, `hooks.ts`.
|
|
30
|
+
|
|
31
|
+
# Использование SDS и Linaria
|
|
32
|
+
|
|
33
|
+
- Для UI‑контролов использовать компоненты из `@sds/*`:
|
|
34
|
+
- кнопки, чекбоксы, поля ввода и т.д.
|
|
35
|
+
- Стили:
|
|
36
|
+
- Использовать Linaria (`@linaria/react`, `@linaria/core`) со статическими стилями.
|
|
37
|
+
- Стили располагать в `styles.ts` рядом с компонентом.
|
|
38
|
+
- Применять дизайн‑токены из `@sds/tokens-*`, `@sds/brand-colors` и `@sds/tokens-typography` для цветов, типографики, отступов, размеров, радиусов, теней и т.д., а не “магические” значения.
|
|
39
|
+
- Избегать:
|
|
40
|
+
- inline‑стилей, кроме самых простых случаев;
|
|
41
|
+
- дублирования CSS, уже представленного в дизайн‑системе;
|
|
42
|
+
- «сырого» CSS вида `#xxxxxx`, `rgb(...)`, произвольных `padding: 17px`, `margin: 23px`, нестандартизированных размеров и теней.
|
|
43
|
+
- Если подходящего токена пока нет, допускается ввод локальных примитивов (например, `const spacingMedium = '16px'`) **в одном месте** с последующим переездом на официальные токены @sds при первой возможности.
|
|
44
|
+
|
|
45
|
+
# Пропсы и типизация
|
|
46
|
+
|
|
47
|
+
- Описывать пропсы через `type Props = { ... }` или `interface Props { ... }`.
|
|
48
|
+
- Не использовать `any`; при необходимости:
|
|
49
|
+
- обобщения (`<T>`), `unknown`, тип‑предикаты и user‑defined type guards.
|
|
50
|
+
- Для доменных сущностей использовать типы из `@/types/**`, а не описывать их заново.
|
|
51
|
+
|
|
52
|
+
# Логика и side effects
|
|
53
|
+
|
|
54
|
+
- Side effects и асинхронщина:
|
|
55
|
+
- по возможности выносить в store (thunk‑и, middleware) или в отдельные хуки.
|
|
56
|
+
- Компоненты не должны:
|
|
57
|
+
- напрямую знать детали API (URL, структура DTO);
|
|
58
|
+
- заниматься маппингом "сырых" DTO — только доменные типы;
|
|
59
|
+
- содержать нетривиальные вычисления и преобразования данных (булевы флаги, сложная склейка строк, агрегаты и т.п.). В большинстве случаев данные для отображения должны быть подготовлены на этапах маппинга/подготовки данных (API -> доменная модель -> store), а компоненты использовать уже готовые поля.
|
|
60
|
+
|
|
61
|
+
# Тестирование UI
|
|
62
|
+
|
|
63
|
+
- Для нетривиальных компонентов добавлять тесты:
|
|
64
|
+
- использовать `@testing-library/react` и `@testing-library/jest-dom`.
|
|
65
|
+
- проверять поведение и бизнес‑правила, а не конкретные CSS‑классы.
|
|
66
|
+
- В тестах ориентироваться на текст, роли и aria‑атрибуты.
|
|
67
|
+
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Redux Toolkit и состояние приложения
|
|
3
|
+
globs: src/store/**/*.ts
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Общие принципы
|
|
8
|
+
|
|
9
|
+
- Использовать **Redux Toolkit**:
|
|
10
|
+
- `createSlice`, `createAsyncThunk`, RTK Query (если используется).
|
|
11
|
+
- Хранить в store **доменные модели**, не "сырые" DTO из API.
|
|
12
|
+
- Все вычисления и преобразования данных (включая вычисляемые поля, булевые флаги, агрегаты, человеко‑читаемые строки и т.п.) должны выполняться **между ответом API и записью в store** — в мапперах или отдельном слое подготовки данных. Store хранит уже подготовленную доменную модель.
|
|
13
|
+
- Разделять:
|
|
14
|
+
- "серверное" состояние (данные из API) и
|
|
15
|
+
- локальное UI‑состояние (выбор/фильтры/флаги).
|
|
16
|
+
|
|
17
|
+
# Структура слайсов
|
|
18
|
+
|
|
19
|
+
- Каждый доменный модуль — свой слайс в `src/store/slices/**`.
|
|
20
|
+
- Слайс экспортирует:
|
|
21
|
+
- `reducer` по умолчанию;
|
|
22
|
+
- `actions` именованным экспортом;
|
|
23
|
+
- селекторы `selectSomething(state: RootState): Type`.
|
|
24
|
+
- Состояние:
|
|
25
|
+
- явный тип для state;
|
|
26
|
+
- аккуратная инициализация initialState.
|
|
27
|
+
|
|
28
|
+
# Асинхронность и сайд‑эффекты
|
|
29
|
+
|
|
30
|
+
- Асинхронные запросы:
|
|
31
|
+
- через `createAsyncThunk` или RTK Query.
|
|
32
|
+
- внутри thunk:
|
|
33
|
+
- вызывать API через сервисы из `@/api/services/**`;
|
|
34
|
+
- не использовать `fetch`/`axios` напрямую.
|
|
35
|
+
- Сайд‑эффекты (логирование, аналитика, работа с файлами):
|
|
36
|
+
- выносить в middleware (`src/store/middleware/**`) или специализированные слайсы.
|
|
37
|
+
|
|
38
|
+
# Типизация
|
|
39
|
+
|
|
40
|
+
- Использовать `RootState`, `AppDispatch` и типизированные хуки `useAppDispatch`, `useAppSelector` (если есть).
|
|
41
|
+
- Для сущностей:
|
|
42
|
+
- доменные типы (включая вычисляемые поля) определять в `@/types/**` и импортировать в слайсы как **источник правды** для структуры данных;
|
|
43
|
+
- избегать дублирования описаний сущностей в нескольких местах.
|
|
44
|
+
|
|
45
|
+
# Тестирование слайсов
|
|
46
|
+
|
|
47
|
+
- Для важных слайсов:
|
|
48
|
+
- тестировать редюсеры (инициализация, основные переходы состояний).
|
|
49
|
+
- тестировать селекторы (включая edge cases).
|
|
50
|
+
- Thunk‑и:
|
|
51
|
+
- по возможности покрывать тестами с моками API‑слоя.
|
|
52
|
+
|
|
53
|
+
# Требование к агенту
|
|
54
|
+
|
|
55
|
+
При изменении/создании слайса:
|
|
56
|
+
- Не класть логику API внутрь редюсеров/компонентов.
|
|
57
|
+
- Строго типизировать state и actions.
|
|
58
|
+
- Использовать единый стиль именования actions и селекторов, как в существующих слайсах.
|
|
59
|
+
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Структура e2e тестов и планов (Playwright)
|
|
3
|
+
globs: app/__tests__/e2e/**/*
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Структура e2e в проекте
|
|
8
|
+
|
|
9
|
+
- Папка e2e: `app/__tests__/e2e/**`.
|
|
10
|
+
- Планы сценариев:
|
|
11
|
+
- `*.cases.md` файлы — **канонический источник сценариев**.
|
|
12
|
+
- Тесты:
|
|
13
|
+
- `*.spec.ts` файлы — реализация сценариев на Playwright.
|
|
14
|
+
- Общие утилиты и абстракции:
|
|
15
|
+
- `app/__tests__/e2e/_shared/**` — константы, fluent‑интерфейсы, хелперы.
|
|
16
|
+
|
|
17
|
+
# Принципы
|
|
18
|
+
|
|
19
|
+
- Каждый сценарий из `*.cases.md` должен иметь соответствующий тест (или набор тестов).
|
|
20
|
+
- **Нельзя** ослаблять проверки в тестах, если это противоречит бизнес‑ожиданиям из планов.
|
|
21
|
+
- Предпочтительно использовать:
|
|
22
|
+
- page‑objects (например, `MedcardRecordsPage.ts`);
|
|
23
|
+
- общие хелперы из `_shared`.
|
|
24
|
+
|
|
25
|
+
# Именование e2e‑тестов
|
|
26
|
+
|
|
27
|
+
- Язык:
|
|
28
|
+
- все названия `test` / `it`, `describe`‑блоков и шагов в `*.cases.md` должны быть сформулированы **на русском языке**, описывая поведение и ожидаемый результат.
|
|
29
|
+
- Формат заголовков e2e‑тестов (`test(...)` / `it(...)`):
|
|
30
|
+
- перед текстовым описанием сценария указывается **префикс с номером** в формате: `ПРЕФИКС-XXX Описание сценария`.
|
|
31
|
+
- `ПРЕФИКС` — аббревиатура из **первых букв слов** тестируемой сущности, записанная **латиницей в верхнем регистре**.
|
|
32
|
+
- пример: `MedcardRecords` → `MR`, `RequestForAnalysis` → `RFA`.
|
|
33
|
+
- `XXX` — порядковый номер теста **с тремя разрядами и лидирующими нулями**: `001`, `002`, `010`, `123` и т.д.
|
|
34
|
+
- пример полного названия e2e‑теста:
|
|
35
|
+
- `test('MR-001 Отображается список записей медкарты', async ({ page }) => { ... })`
|
|
36
|
+
- внутри одной сущности (`ПРЕФИКС`) номера тестов должны образовывать **непротиворечивую последовательность**, без дубликатов номеров.
|
|
37
|
+
|
|
38
|
+
# data-testid для e2e
|
|
39
|
+
|
|
40
|
+
- **Приоритет селекторов:** `data-testid` для стабильных элементов; `getByRole` и `getByLabel` для форм и доступных элементов.
|
|
41
|
+
- **Именование:** схема `{parent}__{element}` (например, `history-page__title`, `history-page__recognition-banner__attach-files-button`).
|
|
42
|
+
- **Где добавлять:** на корневые контейнеры страниц и ключевые интерактивные элементы (кнопки, ссылки, поля), к которым обращаются page objects.
|
|
43
|
+
- **При изменении UI:** обновлять data-testid в компонентах и соответствующие селекторы в page objects; сверять с `*.cases.md`.
|
|
44
|
+
|
|
45
|
+
# Требование к агенту
|
|
46
|
+
|
|
47
|
+
При добавлении/изменении e2e‑тестов:
|
|
48
|
+
- Сначала смотреть соответствующий `*.cases.md` и синхронизировать названия сценариев.
|
|
49
|
+
- Размещать спеки рядом с планами в той же директории.
|
|
50
|
+
- Переиспользовать общие page‑objects и хелперы, а не копировать селекторы напрямую в каждый тест.
|
|
51
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Unit и интеграционные тесты (Jest, Testing Library)
|
|
3
|
+
globs: src/**/*.test.{ts,tsx}
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Общие правила тестирования
|
|
8
|
+
|
|
9
|
+
- Фреймворк: **Jest** + **@testing-library/react**.
|
|
10
|
+
- Основная цель тестов:
|
|
11
|
+
- проверять **поведение и бизнес‑правила**, а не реализацию или внутренние детали.
|
|
12
|
+
- Именование:
|
|
13
|
+
- названия `describe` / `it` / `test` и любые человекочитаемые описания в тестах **должны быть на русском языке**, формулироваться как понятные бизнес‑фразы (что именно ожидается от системы).
|
|
14
|
+
- строки в `describe` / `it` / `test` **должны начинаться с заглавной буквы**.
|
|
15
|
+
|
|
16
|
+
# Тесты компонентов
|
|
17
|
+
|
|
18
|
+
- Использовать `render` из `@testing-library/react`.
|
|
19
|
+
- Ассерты:
|
|
20
|
+
- `@testing-library/jest-dom` (`toBeInTheDocument`, `toHaveTextContent` и т.п.).
|
|
21
|
+
- Взаимодействия:
|
|
22
|
+
- `userEvent` из `@testing-library/user-event`.
|
|
23
|
+
|
|
24
|
+
# Изоляция и моки
|
|
25
|
+
|
|
26
|
+
- Для работы с API/store:
|
|
27
|
+
- мокать store (через test‑store) или использовать MSW, если это принято.
|
|
28
|
+
- Не мокать то, что является частью публичного контракта фичи, если это ломает смысл теста.
|
|
29
|
+
|
|
30
|
+
# Мапперы и преобразование данных
|
|
31
|
+
|
|
32
|
+
- Функции маппинга данных (DTO -> доменная модель и обратно), особенно содержащие вычисляемые поля и ветвления, должны быть покрыты unit‑тестами.
|
|
33
|
+
- В тестах мапперов особое внимание уделять edge‑кейсам и регрессии бизнес‑правил (например, граничные значения, отсутствие полей, неожиданные комбинации значений).
|
|
34
|
+
|
|
35
|
+
# Требование к агенту
|
|
36
|
+
|
|
37
|
+
При добавлении тестов:
|
|
38
|
+
- Следовать существующей структуре и паттернам тестов в `src/**/__tests__/**` или рядом с компонентом.
|
|
39
|
+
- Добавлять тесты для критичных веток логики и edge‑кейсов.
|
|
40
|
+
- При работе с данными:
|
|
41
|
+
- использовать **типы респонса** из API (DTO‑типы), а также **целевые доменные типы** из `@/types/**`, не дублировать интерфейсы в тестах;
|
|
42
|
+
- по возможности опираться на данные и хендлеры мок‑сервера **MSW** из `app/src/mocks/**`, а не плодить случайные тестовые данные "с нуля".
|
|
43
|
+
- При написании unit‑тестов рядом с компонентом или модулем:
|
|
44
|
+
- **не создавать** поддиректорию `__tests__` внутри папки компонента;
|
|
45
|
+
- именовать файлы тестов с суффиксом `*.spec.ts` / `*.spec.tsx`, а не `*.test.ts` / `*.test.tsx`.
|
|
46
|
+
|