paisanos-qa-core 0.1.0
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/paisanos-qa.js +2 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +111 -0
- package/dist/install.d.ts +4 -0
- package/dist/install.js +64 -0
- package/package.json +34 -0
- package/rules/global/auto-test.mdc +37 -0
- package/rules/global/best-practices.mdc +66 -0
- package/rules/global/code-standards.mdc +17 -0
- package/rules/global/file-guard.mdc +36 -0
- package/rules/global/git-commit-guidelines.mdc +227 -0
- package/rules/global/log-process.mdc +111 -0
- package/rules/global/quality-assurance.mdc +102 -0
- package/rules/shared/user-credential-management.mdc +391 -0
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
import { spawn } from 'node:child_process';
|
|
5
|
+
import { program } from 'commander';
|
|
6
|
+
import prompts from 'prompts';
|
|
7
|
+
import { installCoreRules, getInstalledMcpPackages, getPackageBinPath } from './install.js';
|
|
8
|
+
const MODULE_BINS = {
|
|
9
|
+
'paisanos-figma-mcp-qa': 'mcp-figma-qa',
|
|
10
|
+
'paisanos-playwright-mcp': 'playwright-mcp-init',
|
|
11
|
+
'paisanos-maestro-mcp': 'maestro-mcp-init',
|
|
12
|
+
};
|
|
13
|
+
const MODULE_LABELS = {
|
|
14
|
+
'paisanos-figma-mcp-qa': 'Design (Figma MCP, design validation)',
|
|
15
|
+
'paisanos-playwright-mcp': 'Web (Playwright E2E)',
|
|
16
|
+
'paisanos-maestro-mcp': 'Mobile (Maestro)',
|
|
17
|
+
};
|
|
18
|
+
program
|
|
19
|
+
.name('paisanos-qa')
|
|
20
|
+
.description('Bootstrap QA rules and MCP config for Cursor. Choose what to install.')
|
|
21
|
+
.option('-C, --cwd <path>', 'Project root (default: current directory)')
|
|
22
|
+
.option('--core', 'Install only core rules (no prompt)')
|
|
23
|
+
.option('--design', 'Include Design/Figma MCP')
|
|
24
|
+
.option('--web', 'Include Web/Playwright MCP')
|
|
25
|
+
.option('--mobile', 'Include Mobile/Maestro MCP')
|
|
26
|
+
.option('--all', 'Include all: Design, Web, Mobile')
|
|
27
|
+
.action(async (opts) => {
|
|
28
|
+
const cwd = opts.cwd ? resolve(process.cwd(), opts.cwd) : process.cwd();
|
|
29
|
+
if (!existsSync(resolve(cwd, 'package.json'))) {
|
|
30
|
+
console.error('Error: No package.json found. Run from project root.');
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
const installed = getInstalledMcpPackages(cwd);
|
|
34
|
+
let selected = [];
|
|
35
|
+
if (opts.core) {
|
|
36
|
+
selected = [];
|
|
37
|
+
}
|
|
38
|
+
else if (opts.all) {
|
|
39
|
+
selected = installed;
|
|
40
|
+
}
|
|
41
|
+
else if (opts.design || opts.web || opts.mobile) {
|
|
42
|
+
if (opts.design && installed.includes('paisanos-figma-mcp-qa'))
|
|
43
|
+
selected.push('paisanos-figma-mcp-qa');
|
|
44
|
+
if (opts.web && installed.includes('paisanos-playwright-mcp'))
|
|
45
|
+
selected.push('paisanos-playwright-mcp');
|
|
46
|
+
if (opts.mobile && installed.includes('paisanos-maestro-mcp'))
|
|
47
|
+
selected.push('paisanos-maestro-mcp');
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
const allPkgs = ['paisanos-figma-mcp-qa', 'paisanos-playwright-mcp', 'paisanos-maestro-mcp'];
|
|
51
|
+
const choices = allPkgs.map((pkg) => {
|
|
52
|
+
const isInstalled = installed.includes(pkg);
|
|
53
|
+
return {
|
|
54
|
+
title: MODULE_LABELS[pkg],
|
|
55
|
+
value: pkg,
|
|
56
|
+
description: isInstalled ? 'installed' : 'pnpm add -D ' + pkg,
|
|
57
|
+
disabled: !isInstalled,
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
const { modules } = await prompts({
|
|
61
|
+
type: 'multiselect',
|
|
62
|
+
name: 'modules',
|
|
63
|
+
message: 'What would you like to set up? (Core rules always installed)',
|
|
64
|
+
choices,
|
|
65
|
+
min: 0,
|
|
66
|
+
hint: 'Space to select, Enter to confirm. Install packages first for more options.',
|
|
67
|
+
});
|
|
68
|
+
if (modules === undefined) {
|
|
69
|
+
console.log('Cancelled.');
|
|
70
|
+
process.exit(0);
|
|
71
|
+
}
|
|
72
|
+
selected = modules.filter((m) => installed.includes(m));
|
|
73
|
+
}
|
|
74
|
+
console.log('\nInstalling QA Core rules...');
|
|
75
|
+
const coreInstalled = installCoreRules(cwd);
|
|
76
|
+
for (const p of coreInstalled) {
|
|
77
|
+
console.log(` ${p}`);
|
|
78
|
+
}
|
|
79
|
+
for (const pkg of selected) {
|
|
80
|
+
const binName = MODULE_BINS[pkg];
|
|
81
|
+
if (!binName)
|
|
82
|
+
continue;
|
|
83
|
+
const binPath = getPackageBinPath(cwd, pkg, binName);
|
|
84
|
+
if (!binPath) {
|
|
85
|
+
console.warn(`\nWarning: Could not find bin ${binName} for ${pkg}`);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
console.log(`\nRunning ${MODULE_LABELS[pkg]}...`);
|
|
89
|
+
await new Promise((resolvePromise, reject) => {
|
|
90
|
+
const child = spawn(process.execPath, [binPath], {
|
|
91
|
+
cwd,
|
|
92
|
+
stdio: 'inherit',
|
|
93
|
+
});
|
|
94
|
+
child.on('close', (code) => {
|
|
95
|
+
if (code === 0)
|
|
96
|
+
resolvePromise();
|
|
97
|
+
else
|
|
98
|
+
reject(new Error(`${binName} exited with ${code}`));
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
const notInstalled = selected.filter((p) => !installed.includes(p));
|
|
103
|
+
if (notInstalled.length > 0) {
|
|
104
|
+
console.log('\nTo install selected modules:');
|
|
105
|
+
for (const pkg of notInstalled) {
|
|
106
|
+
console.log(` pnpm add -D ${pkg}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
console.log('\nDone.');
|
|
110
|
+
});
|
|
111
|
+
program.parse();
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function installCoreRules(projectRoot: string): string[];
|
|
2
|
+
export declare function isPackageInstalled(projectRoot: string, packageName: string): boolean;
|
|
3
|
+
export declare function getInstalledMcpPackages(projectRoot: string): string[];
|
|
4
|
+
export declare function getPackageBinPath(projectRoot: string, packageName: string, binName: string): string | null;
|
package/dist/install.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { copyFileSync, mkdirSync, existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join, dirname } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
5
|
+
const PACKAGE_ROOT = join(__dirname, '..');
|
|
6
|
+
const RULES_SRC = join(PACKAGE_ROOT, 'rules');
|
|
7
|
+
export function installCoreRules(projectRoot) {
|
|
8
|
+
const installed = [];
|
|
9
|
+
const cursorDir = join(projectRoot, '.cursor');
|
|
10
|
+
const rulesDir = join(cursorDir, 'rules', 'rules-kit');
|
|
11
|
+
const globalDir = join(rulesDir, 'global');
|
|
12
|
+
const sharedDir = join(rulesDir, 'shared');
|
|
13
|
+
mkdirSync(globalDir, { recursive: true });
|
|
14
|
+
mkdirSync(sharedDir, { recursive: true });
|
|
15
|
+
const globalRules = readdirSync(join(RULES_SRC, 'global')).filter((f) => f.endsWith('.mdc'));
|
|
16
|
+
for (const name of globalRules) {
|
|
17
|
+
const src = join(RULES_SRC, 'global', name);
|
|
18
|
+
const dest = join(globalDir, name);
|
|
19
|
+
copyFileSync(src, dest);
|
|
20
|
+
installed.push(`.cursor/rules/rules-kit/global/${name}`);
|
|
21
|
+
}
|
|
22
|
+
const sharedRules = readdirSync(join(RULES_SRC, 'shared')).filter((f) => f.endsWith('.mdc'));
|
|
23
|
+
for (const name of sharedRules) {
|
|
24
|
+
const src = join(RULES_SRC, 'shared', name);
|
|
25
|
+
const dest = join(sharedDir, name);
|
|
26
|
+
copyFileSync(src, dest);
|
|
27
|
+
installed.push(`.cursor/rules/rules-kit/shared/${name}`);
|
|
28
|
+
}
|
|
29
|
+
return installed;
|
|
30
|
+
}
|
|
31
|
+
const MCP_PACKAGES = ['paisanos-figma-mcp-qa', 'paisanos-playwright-mcp', 'paisanos-maestro-mcp'];
|
|
32
|
+
export function isPackageInstalled(projectRoot, packageName) {
|
|
33
|
+
const paths = [
|
|
34
|
+
join(projectRoot, 'node_modules', packageName, 'package.json'),
|
|
35
|
+
join(projectRoot, 'node_modules', 'paisanos-qa', 'node_modules', packageName, 'package.json'),
|
|
36
|
+
];
|
|
37
|
+
return paths.some((p) => existsSync(p));
|
|
38
|
+
}
|
|
39
|
+
export function getInstalledMcpPackages(projectRoot) {
|
|
40
|
+
const installed = [];
|
|
41
|
+
for (const pkg of MCP_PACKAGES) {
|
|
42
|
+
if (isPackageInstalled(projectRoot, pkg)) {
|
|
43
|
+
installed.push(pkg);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return installed;
|
|
47
|
+
}
|
|
48
|
+
export function getPackageBinPath(projectRoot, packageName, binName) {
|
|
49
|
+
const possibleRoots = [
|
|
50
|
+
join(projectRoot, 'node_modules', packageName),
|
|
51
|
+
join(projectRoot, 'node_modules', 'paisanos-qa', 'node_modules', packageName),
|
|
52
|
+
];
|
|
53
|
+
for (const pkgRoot of possibleRoots) {
|
|
54
|
+
const pkgJsonPath = join(pkgRoot, 'package.json');
|
|
55
|
+
if (!existsSync(pkgJsonPath))
|
|
56
|
+
continue;
|
|
57
|
+
const pkg = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));
|
|
58
|
+
const binPath = pkg.bin?.[binName];
|
|
59
|
+
if (binPath) {
|
|
60
|
+
return join(pkgRoot, binPath);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "paisanos-qa-core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "QA rules and criteria - cross-product denominator for Paisanos",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"paisanos-qa": "./bin/paisanos-qa.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"bin",
|
|
12
|
+
"dist",
|
|
13
|
+
"rules"
|
|
14
|
+
],
|
|
15
|
+
"keywords": [
|
|
16
|
+
"qa",
|
|
17
|
+
"cursor",
|
|
18
|
+
"rules",
|
|
19
|
+
"testing"
|
|
20
|
+
],
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"commander": "^12",
|
|
24
|
+
"prompts": "^2.4.2"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/node": "^20",
|
|
28
|
+
"@types/prompts": "^2.4.9",
|
|
29
|
+
"typescript": "^5"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsc"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
projectPath: ./
|
|
3
|
+
cursorPath: .
|
|
4
|
+
description: Guidelines for automated testing
|
|
5
|
+
globs: **/*
|
|
6
|
+
alwaysApply: true
|
|
7
|
+
---
|
|
8
|
+
# Automated Testing
|
|
9
|
+
|
|
10
|
+
Run the test suite after each change and fix issues until all tests pass.
|
|
11
|
+
|
|
12
|
+
## Testing Workflow
|
|
13
|
+
|
|
14
|
+
1. **Run Tests Frequently**: Execute tests after implementing each logical component.
|
|
15
|
+
2. **Fix Issues Immediately**: Address test failures as soon as they appear.
|
|
16
|
+
3. **Regression Testing**: Ensure existing functionality remains intact.
|
|
17
|
+
4. **Test Coverage**: Add new tests when implementing new features.
|
|
18
|
+
|
|
19
|
+
## Common Test Commands
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Framework-specific test commands
|
|
23
|
+
npm test # Node.js/JavaScript
|
|
24
|
+
php artisan test # Laravel
|
|
25
|
+
ng test # Angular
|
|
26
|
+
mvn test # Java/Maven
|
|
27
|
+
pytest # Python
|
|
28
|
+
go test ./... # Go
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Test-Driven Development
|
|
32
|
+
|
|
33
|
+
Consider adopting TDD principles:
|
|
34
|
+
|
|
35
|
+
1. Write a failing test first
|
|
36
|
+
2. Implement the minimal code to pass the test
|
|
37
|
+
3. Refactor while keeping tests passing
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
projectPath: ./
|
|
3
|
+
cursorPath: .
|
|
4
|
+
description: Global best practices for any development project
|
|
5
|
+
globs: **/*
|
|
6
|
+
alwaysApply: true
|
|
7
|
+
---
|
|
8
|
+
# Global Best Practices
|
|
9
|
+
|
|
10
|
+
This document defines best practices applicable to any development project, regardless of the technology stack used.
|
|
11
|
+
|
|
12
|
+
## General Principles
|
|
13
|
+
|
|
14
|
+
- **Code Quality**: Maintain high quality standards throughout all code.
|
|
15
|
+
- **Documentation**: Update documentation when functionality changes.
|
|
16
|
+
- **Testing**: Implement tests for all new or modified code.
|
|
17
|
+
- **Single Responsibility**: Each component should have a single responsibility.
|
|
18
|
+
- **DRY (Don't Repeat Yourself)**: Avoid duplication of code and logic.
|
|
19
|
+
|
|
20
|
+
## Code Development and Modification
|
|
21
|
+
|
|
22
|
+
When creating or modifying any component of the system, follow these guidelines:
|
|
23
|
+
|
|
24
|
+
### Development Process
|
|
25
|
+
|
|
26
|
+
1. **Context Understanding**: Fully understand the problem before writing code.
|
|
27
|
+
2. **Prior Design**: Design the solution before implementing it.
|
|
28
|
+
3. **Incremental Development**: Implement in small, verifiable increments.
|
|
29
|
+
4. **Code Review**: Review code before considering it complete.
|
|
30
|
+
5. **Refactoring**: Improve existing code without changing its behavior.
|
|
31
|
+
|
|
32
|
+
### Testing
|
|
33
|
+
|
|
34
|
+
1. **Test First**: Consider writing tests before implementing code (TDD when possible).
|
|
35
|
+
2. **Coverage**: Ensure new features have adequate tests.
|
|
36
|
+
3. **Automation**: Run tests automatically before committing changes.
|
|
37
|
+
4. **Verification**: Ensure all tests pass before finalizing.
|
|
38
|
+
|
|
39
|
+
### Quality and Maintenance
|
|
40
|
+
|
|
41
|
+
1. **Error Handling**: Implement appropriate error and exception handling.
|
|
42
|
+
2. **Logging**: Add appropriate logs to facilitate debugging and monitoring.
|
|
43
|
+
3. **Security**: Consider security implications in every change.
|
|
44
|
+
4. **Performance**: Evaluate the performance impact of changes made.
|
|
45
|
+
|
|
46
|
+
## Source Code Management
|
|
47
|
+
|
|
48
|
+
1. **Version Control**: Properly use the version control system.
|
|
49
|
+
2. **Small Commits**: Make small, focused commits with specific purposes.
|
|
50
|
+
3. **Descriptive Messages**: Write clear and descriptive commit messages.
|
|
51
|
+
4. **Working Branches**: Use branches for features, fixes, or tasks.
|
|
52
|
+
5. **Pull Requests**: Request code review through pull requests.
|
|
53
|
+
|
|
54
|
+
## Problem Solving
|
|
55
|
+
|
|
56
|
+
1. **Root Cause Analysis**: Identify the fundamental cause of problems.
|
|
57
|
+
2. **Durable Solutions**: Implement solutions that address the root problem.
|
|
58
|
+
3. **Solution Documentation**: Document complex problems and their solutions.
|
|
59
|
+
4. **Continuous Learning**: Learn from mistakes and continuously improve.
|
|
60
|
+
|
|
61
|
+
## Teamwork
|
|
62
|
+
|
|
63
|
+
1. **Clear Communication**: Communicate changes and design decisions to the team.
|
|
64
|
+
2. **Collaboration**: Collaborate with other team members on complex problems.
|
|
65
|
+
3. **Knowledge Sharing**: Document and share knowledge with the team.
|
|
66
|
+
4. **Code Reviews**: Participate in code reviews constructively.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
projectPath: ./
|
|
3
|
+
cursorPath: .
|
|
4
|
+
description: General code formatting standards
|
|
5
|
+
globs: **/*
|
|
6
|
+
alwaysApply: true
|
|
7
|
+
---
|
|
8
|
+
# Global Code Standards
|
|
9
|
+
|
|
10
|
+
- Follow consistent code formatting across the entire project.
|
|
11
|
+
- Use meaningful variable and function names that explain their purpose.
|
|
12
|
+
- Keep functions small and focused on a single responsibility.
|
|
13
|
+
- Add meaningful comments for complex logic, but avoid obvious comments.
|
|
14
|
+
- Remove debug code, commented-out code and console logs before committing.
|
|
15
|
+
- Use proper indentation (spaces or tabs) consistently throughout the project.
|
|
16
|
+
- Follow the language/framework's standard style guide.
|
|
17
|
+
- Avoid deep nesting of conditionals and loops.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
projectPath: ./
|
|
3
|
+
cursorPath: .
|
|
4
|
+
description: File operation guidelines to prevent content loss
|
|
5
|
+
globs: **/*
|
|
6
|
+
alwaysApply: true
|
|
7
|
+
---
|
|
8
|
+
# File Management Guard
|
|
9
|
+
|
|
10
|
+
Before creating a file, check if it already exists. If it exists and there is no explicit instruction to overwrite, merge content instead of replacing.
|
|
11
|
+
|
|
12
|
+
## Best Practices for File Operations
|
|
13
|
+
|
|
14
|
+
1. **Check Existence**: Always verify if a file exists before creating it.
|
|
15
|
+
2. **Preserve Content**: When a file exists, preserve important elements:
|
|
16
|
+
|
|
17
|
+
- Comments and documentation
|
|
18
|
+
- Existing imports
|
|
19
|
+
- License headers
|
|
20
|
+
- Configuration settings
|
|
21
|
+
|
|
22
|
+
3. **Merge Strategies**:
|
|
23
|
+
|
|
24
|
+
- For code files: Add new functions, classes, or methods without removing existing ones
|
|
25
|
+
- For configuration files: Add new settings while preserving existing ones
|
|
26
|
+
- For documentation: Append new information or integrate it with existing content
|
|
27
|
+
|
|
28
|
+
4. **Communicate Changes**: When modifying existing files, document the nature of the changes.
|
|
29
|
+
|
|
30
|
+
## When to Overwrite
|
|
31
|
+
|
|
32
|
+
Only overwrite files when:
|
|
33
|
+
|
|
34
|
+
1. Explicitly instructed to do so
|
|
35
|
+
2. The file is known to be a generated file that should be recreated
|
|
36
|
+
3. The entire purpose of the file is being changed
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
---
|
|
2
|
+
projectPath: ./
|
|
3
|
+
cursorPath: .
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
globs: **/*
|
|
6
|
+
---
|
|
7
|
+
# Git Commit Guidelines - CRITICAL VERSION CONTROL
|
|
8
|
+
|
|
9
|
+
## ⚠️ CRITICAL WARNING - BREAKING CHANGES
|
|
10
|
+
|
|
11
|
+
**NEVER use `BREAKING CHANGE:` in commit messages unless it's a REAL breaking change that requires users to modify their code!**
|
|
12
|
+
|
|
13
|
+
This project uses semantic-release which automatically triggers version bumps:
|
|
14
|
+
|
|
15
|
+
| Type | Emoji | Example | Version Impact | Risk Level |
|
|
16
|
+
| ------------------ | ----- | --------------------------------------- | -------------- | ---------------- |
|
|
17
|
+
| `fix:` | 🐛 | `fix(payment): 🐛 handle timeout error` | PATCH | ✅ Safe |
|
|
18
|
+
| `feat:` | ✨ | `feat(api): ✨ add user authentication` | MINOR | ✅ Safe |
|
|
19
|
+
| `docs:` | 📝 | `docs(readme): 📝 clarify setup` | No version | ✅ Safe |
|
|
20
|
+
| `refactor:` | ♻️ | `refactor(core): ♻️ extract helper` | No version | ✅ Safe |
|
|
21
|
+
| `test:` | ✅ | `test(utils): ✅ edge cases for parser` | No version | ✅ Safe |
|
|
22
|
+
| `chore:` | 🔧 | `chore(ci): 🔧 bump node version` | No version | ✅ Safe |
|
|
23
|
+
| `BREAKING CHANGE:` | 🚨 | Any commit with this footer | MAJOR | 🚨 **DANGEROUS** |
|
|
24
|
+
|
|
25
|
+
## ⚠️ Breaking Changes (MAJOR version) - USE WITH EXTREME CAUTION
|
|
26
|
+
|
|
27
|
+
**WARNING**: Only use `BREAKING CHANGE:` when users MUST modify their code to continue using the project.
|
|
28
|
+
|
|
29
|
+
### 🚨 Real Breaking Changes (Only when absolutely necessary):
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
feat: ✨ redesign authentication system
|
|
33
|
+
|
|
34
|
+
Complete overhaul of auth flow and API structure
|
|
35
|
+
|
|
36
|
+
BREAKING CHANGE: Auth token format changed, all clients must update their integration
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### ❌ WRONG - These are NOT breaking changes:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# ❌ Adding new features is NOT breaking
|
|
43
|
+
feat: ✨ add new dashboard feature
|
|
44
|
+
|
|
45
|
+
BREAKING CHANGE: Added new dashboard # WRONG!
|
|
46
|
+
|
|
47
|
+
# ❌ Improving existing features is NOT breaking
|
|
48
|
+
feat: ✨ improve performance
|
|
49
|
+
|
|
50
|
+
BREAKING CHANGE: Better caching system # WRONG!
|
|
51
|
+
|
|
52
|
+
# ❌ Internal refactoring is NOT breaking
|
|
53
|
+
refactor: ♻️ reorganize code structure
|
|
54
|
+
|
|
55
|
+
BREAKING CHANGE: Changed internal structure # WRONG!
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### ❌ Dangerous Patterns to AVOID:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# DON'T use exclamation mark in type
|
|
62
|
+
feat!: ✨ breaking change
|
|
63
|
+
|
|
64
|
+
# DON'T add BREAKING CHANGE for non-breaking changes
|
|
65
|
+
feat: 🎉 add cool new feature
|
|
66
|
+
|
|
67
|
+
BREAKING CHANGE: Users now have more options # NOT BREAKING!
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## **Semantic Versioning Impact**
|
|
71
|
+
|
|
72
|
+
| Version Type | When to Use | Result | Example |
|
|
73
|
+
| ------------------ | --------------------------------- | ------------------------- | -------------------------------- |
|
|
74
|
+
| **PATCH** (v1.0.1) | Bug fixes, backward-compatible | `fix:` type | `fix: 🐛 handle null values` |
|
|
75
|
+
| **MINOR** (v1.1.0) | New features, backward-compatible | `feat:` type | `feat: ✨ add user dashboard` |
|
|
76
|
+
| **MAJOR** (v2.0.0) | 🚨 Breaking changes only | `BREAKING CHANGE:` footer | Only when users must change code |
|
|
77
|
+
|
|
78
|
+
### 🎯 Safe Approach (Recommended):
|
|
79
|
+
|
|
80
|
+
- **Default to `fix:`** when in doubt
|
|
81
|
+
- **Use `feat:`** for new functionality
|
|
82
|
+
- **NEVER use `BREAKING CHANGE:`** unless absolutely certain
|
|
83
|
+
|
|
84
|
+
## Author Identity Rules
|
|
85
|
+
|
|
86
|
+
To clearly differentiate the origin of each commit, **ALWAYS** use `--author` according to context:
|
|
87
|
+
|
|
88
|
+
### Human Developer Commits
|
|
89
|
+
|
|
90
|
+
Commits made directly by human developers:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# Use developer's normal identity (without --author)
|
|
94
|
+
git commit -m "feat(auth): ✨ implement OAuth login"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### AI Assistant Commits
|
|
98
|
+
|
|
99
|
+
Commits made by AI assistants (Cursor, Claude, ChatGPT, etc.):
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# MANDATORY use --author with AI identification
|
|
103
|
+
git commit --author="Claude AI <claude.ai@assistant.local>" -m "feat(api): ✨ add user validation"
|
|
104
|
+
git commit --author="Cursor AI <cursor.ai@assistant.local>" -m "fix(auth): 🐛 handle token expiry"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Available AI Author Formats:
|
|
108
|
+
|
|
109
|
+
- `Agent AI <agent.ai@assistant.local>` - For general AI assistants
|
|
110
|
+
- `Claude AI <claude.ai@assistant.local>` - For Claude/Sonnet
|
|
111
|
+
- `Cursor AI <cursor.ai@assistant.local>` - For Cursor IDE AI
|
|
112
|
+
- `ChatGPT AI <chatgpt.ai@assistant.local>` - For ChatGPT
|
|
113
|
+
- `Copilot AI <copilot.ai@assistant.local>` - For GitHub Copilot
|
|
114
|
+
|
|
115
|
+
### 🤖 AI Assistant Commit Guidelines:
|
|
116
|
+
|
|
117
|
+
**CRITICAL RULES for AI Assistants:**
|
|
118
|
+
|
|
119
|
+
1. **ALWAYS use `--author="Agent AI <agent.ai@assistant.local>"`**
|
|
120
|
+
2. **Prefer `fix:` over `feat:` when uncertain**
|
|
121
|
+
3. **NEVER use `BREAKING CHANGE:` without explicit user confirmation**
|
|
122
|
+
4. **Keep commit messages concise and descriptive**
|
|
123
|
+
5. **When in doubt, ask the user before committing**
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
# ✅ CORRECT AI commit examples:
|
|
127
|
+
git commit --author="Agent AI <agent.ai@assistant.local>" -m "fix: 🐛 correct validation logic"
|
|
128
|
+
git commit --author="Agent AI <agent.ai@assistant.local>" -m "feat: ✨ add new component"
|
|
129
|
+
git commit --author="Agent AI <agent.ai@assistant.local>" -m "docs: 📝 update README"
|
|
130
|
+
|
|
131
|
+
# ❌ NEVER do this without user approval:
|
|
132
|
+
git commit --author="Agent AI <agent.ai@assistant.local>" -m "feat: ✨ redesign API
|
|
133
|
+
|
|
134
|
+
BREAKING CHANGE: Changed endpoint structure"
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Automated System Commits
|
|
138
|
+
|
|
139
|
+
Automatic commits (semantic-release, bots, CI/CD):
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# These systems already configure their own author automatically
|
|
143
|
+
# No manual action required
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Important Notes
|
|
147
|
+
|
|
148
|
+
- **Avatar Display**: Avatar is determined by email. Emails not associated with GitHub accounts will show default avatar
|
|
149
|
+
- **Consistency**: Maintain consistency in AI email format: `<ai-name>.ai@assistant.local`
|
|
150
|
+
- **Transparency**: This practice improves transparency and traceability of collaborative development
|
|
151
|
+
|
|
152
|
+
## 📚 Project History & Lessons Learned
|
|
153
|
+
|
|
154
|
+
### ⚠️ Previous Versioning Issues:
|
|
155
|
+
|
|
156
|
+
This project has experienced accidental major version bumps due to incorrect `BREAKING CHANGE:` usage:
|
|
157
|
+
|
|
158
|
+
- **v3.0.0**: Accidentally triggered by incorrect `BREAKING CHANGE:` in commit
|
|
159
|
+
- **v3.0.1**: Another accidental major bump
|
|
160
|
+
- **Current version**: v3.3.1+ (continuing from accidental major versions)
|
|
161
|
+
|
|
162
|
+
### 🎯 Lessons Learned:
|
|
163
|
+
|
|
164
|
+
1. **`BREAKING CHANGE:` is extremely powerful** - it immediately triggers major version
|
|
165
|
+
2. **Most changes are NOT breaking** - adding features, improving performance, refactoring
|
|
166
|
+
3. **When in doubt, use `fix:` or `feat:`** - these are safer options
|
|
167
|
+
4. **Breaking changes require user code modifications** - not just "big changes"
|
|
168
|
+
|
|
169
|
+
### 🔒 Current Policy:
|
|
170
|
+
|
|
171
|
+
- **Default to `fix:`** for improvements and corrections
|
|
172
|
+
- **Use `feat:`** only for clear new functionality
|
|
173
|
+
- **Avoid `BREAKING CHANGE:`** unless users must modify their code to continue using the project
|
|
174
|
+
|
|
175
|
+
## BREAKING CHANGE Best Practices (Use Sparingly)
|
|
176
|
+
|
|
177
|
+
**Only when users MUST change their code:**
|
|
178
|
+
|
|
179
|
+
1. **Keep title short**: Under 72 characters
|
|
180
|
+
2. **Use blank line**: Separate title from BREAKING CHANGE
|
|
181
|
+
3. **Be specific**: Explain what changed and impact
|
|
182
|
+
4. **Add context**: Include migration notes if needed
|
|
183
|
+
5. **Get approval**: Always get explicit user approval before using
|
|
184
|
+
|
|
185
|
+
### Examples:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
# Good for major feature
|
|
189
|
+
feat: 🎉 redesign user interface
|
|
190
|
+
|
|
191
|
+
New component library and design system
|
|
192
|
+
|
|
193
|
+
BREAKING CHANGE: Button component props changed, see migration guide
|
|
194
|
+
|
|
195
|
+
# Good for simple breaking change
|
|
196
|
+
feat: ✨ update API endpoints
|
|
197
|
+
|
|
198
|
+
BREAKING CHANGE: All endpoints now require v2 prefix
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Release Guidelines
|
|
202
|
+
|
|
203
|
+
### When NOT to Create Releases
|
|
204
|
+
|
|
205
|
+
- **Default Behavior**: Do NOT create releases unless explicitly requested
|
|
206
|
+
- **Check Existing Automation**: Before attempting any release, verify if automation already exists:
|
|
207
|
+
- GitHub Actions workflows (`.github/workflows/`)
|
|
208
|
+
- GitLab CI/CD pipelines (`.gitlab-ci.yml`)
|
|
209
|
+
- `semantic-release` in `package.json` dependencies
|
|
210
|
+
- Other automated release tools
|
|
211
|
+
|
|
212
|
+
### When to Create Releases
|
|
213
|
+
|
|
214
|
+
Only create releases when:
|
|
215
|
+
|
|
216
|
+
1. **Explicitly requested** by the user
|
|
217
|
+
2. **No existing automation** is found
|
|
218
|
+
3. **Manual release process** is confirmed to be needed
|
|
219
|
+
|
|
220
|
+
### Release Verification Commands
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
# Check for existing automation
|
|
224
|
+
ls .github/workflows/
|
|
225
|
+
cat package.json | grep semantic-release
|
|
226
|
+
cat .gitlab-ci.yml 2>/dev/null || echo "No GitLab CI found"
|
|
227
|
+
```
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
projectPath: ./
|
|
3
|
+
cursorPath: .
|
|
4
|
+
description: Guidelines for process logging
|
|
5
|
+
globs: **/*
|
|
6
|
+
alwaysApply: true
|
|
7
|
+
---
|
|
8
|
+
# Task Process Logging
|
|
9
|
+
|
|
10
|
+
For long or complex tasks, maintain a detailed log in `docs/logs-process/YYYY-MM-DD_<task-name>.md`. This practice improves task tracking, knowledge sharing, and project documentation.
|
|
11
|
+
|
|
12
|
+
## Log Structure
|
|
13
|
+
|
|
14
|
+
Each process log should include:
|
|
15
|
+
|
|
16
|
+
1. **Title**: Clear description of the task with date
|
|
17
|
+
2. **Objectives**: What you are trying to accomplish
|
|
18
|
+
3. **Prerequisites**: Requirements and dependencies
|
|
19
|
+
4. **Task Breakdown**: Checklist of subtasks
|
|
20
|
+
5. **Process Notes**: Observations made during implementation
|
|
21
|
+
6. **Problems & Solutions**: Issues encountered and how they were resolved
|
|
22
|
+
7. **Decisions**: Important decisions and their rationale
|
|
23
|
+
8. **Result**: Final outcome and verification steps
|
|
24
|
+
9. **Future Considerations**: Notes for future improvements
|
|
25
|
+
|
|
26
|
+
## Log Template
|
|
27
|
+
|
|
28
|
+
```markdown
|
|
29
|
+
# Task: [Task Name] - YYYY-MM-DD
|
|
30
|
+
|
|
31
|
+
## Objectives
|
|
32
|
+
|
|
33
|
+
- Primary objective
|
|
34
|
+
- Secondary objectives
|
|
35
|
+
|
|
36
|
+
## Prerequisites
|
|
37
|
+
|
|
38
|
+
- Required tools
|
|
39
|
+
- Required permissions/access
|
|
40
|
+
- Related documentation
|
|
41
|
+
|
|
42
|
+
## Task Breakdown
|
|
43
|
+
|
|
44
|
+
- [ ] Step 1: [Description]
|
|
45
|
+
- [ ] Step 2: [Description]
|
|
46
|
+
- [ ] Step 3: [Description]
|
|
47
|
+
|
|
48
|
+
## Process Notes
|
|
49
|
+
|
|
50
|
+
- [Timestamp] Observation or implementation detail
|
|
51
|
+
- [Timestamp] Another observation
|
|
52
|
+
|
|
53
|
+
## Problems & Solutions
|
|
54
|
+
|
|
55
|
+
### Problem 1: [Problem description]
|
|
56
|
+
|
|
57
|
+
- Attempted solution 1: [Result]
|
|
58
|
+
- Attempted solution 2: [Result]
|
|
59
|
+
- Final solution: [Implementation details]
|
|
60
|
+
|
|
61
|
+
### Problem 2: [Problem description]
|
|
62
|
+
|
|
63
|
+
- Solution: [Implementation details]
|
|
64
|
+
|
|
65
|
+
## Decisions
|
|
66
|
+
|
|
67
|
+
- Decision 1: [What was decided]
|
|
68
|
+
Rationale: [Why this choice was made]
|
|
69
|
+
Alternatives considered: [What else was considered]
|
|
70
|
+
|
|
71
|
+
## Result
|
|
72
|
+
|
|
73
|
+
- Success/Partial success/Failure
|
|
74
|
+
- Verification steps performed
|
|
75
|
+
- Evidence of completion
|
|
76
|
+
|
|
77
|
+
## Future Considerations
|
|
78
|
+
|
|
79
|
+
- Potential improvements
|
|
80
|
+
- Related tasks that should be considered later
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Best Practices
|
|
84
|
+
|
|
85
|
+
1. **Real-time Updates**: Update the log while working on the task, not after completion
|
|
86
|
+
2. **Detailed Problems**: Document all encountered problems, even if solved quickly
|
|
87
|
+
3. **Command Logging**: Record exact commands used for future reference
|
|
88
|
+
4. **Versioning**: Include version numbers of tools/libraries used
|
|
89
|
+
5. **Screenshots**: Include screenshots of important states or errors
|
|
90
|
+
6. **Time Tracking**: Note timestamps for major steps to help estimate similar tasks
|
|
91
|
+
|
|
92
|
+
## When to Create Process Logs
|
|
93
|
+
|
|
94
|
+
Create logs for:
|
|
95
|
+
|
|
96
|
+
- System architecture changes
|
|
97
|
+
- Complex bug fixes
|
|
98
|
+
- Major feature implementations
|
|
99
|
+
- Configuration changes
|
|
100
|
+
- Data migrations
|
|
101
|
+
- Performance optimizations
|
|
102
|
+
- Security-related changes
|
|
103
|
+
- Anything that might need to be referred to later
|
|
104
|
+
|
|
105
|
+
## Integration with Workflow
|
|
106
|
+
|
|
107
|
+
1. Create log file at task initiation
|
|
108
|
+
2. Update throughout implementation
|
|
109
|
+
3. Review and finalize before marking task complete
|
|
110
|
+
4. Reference in commit messages and pull requests
|
|
111
|
+
5. Share with team members for knowledge transfer
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
projectPath: ./
|
|
3
|
+
cursorPath: .
|
|
4
|
+
description: Quality control practices for all projects
|
|
5
|
+
globs: **/*
|
|
6
|
+
alwaysApply: true
|
|
7
|
+
---
|
|
8
|
+
# Project Quality Assurance
|
|
9
|
+
|
|
10
|
+
This document unifies quality control practices applicable to any project, regardless of the technology stack used.
|
|
11
|
+
|
|
12
|
+
## Quality Principles
|
|
13
|
+
|
|
14
|
+
1. **Continuous Verification**: Constantly verify code quality throughout development.
|
|
15
|
+
2. **Error Prevention**: Preventing errors is better than correcting them later.
|
|
16
|
+
3. **Continuous Improvement**: Continually seek ways to improve processes and code.
|
|
17
|
+
4. **Documentation**: Maintain accurate documentation of processes and decisions.
|
|
18
|
+
|
|
19
|
+
## Automated Testing
|
|
20
|
+
|
|
21
|
+
- **Regular Execution**: Run automated test suites after each significant change.
|
|
22
|
+
- **Problem Resolution**: Don't consider a change complete until all tests pass.
|
|
23
|
+
- **Coverage**: Add new tests for new or modified code.
|
|
24
|
+
- **Regression**: Ensure changes don't break existing functionality.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Run tests and verify all pass
|
|
28
|
+
npm run test
|
|
29
|
+
|
|
30
|
+
# Framework-specific test commands
|
|
31
|
+
php artisan test # Laravel
|
|
32
|
+
ng test # Angular
|
|
33
|
+
pytest # Python
|
|
34
|
+
go test ./... # Go
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Process Logging
|
|
38
|
+
|
|
39
|
+
For complex or long-running tasks, maintain a process log:
|
|
40
|
+
|
|
41
|
+
1. **Checklist Creation**: Create a log file in `docs/logs-process/`.
|
|
42
|
+
2. **Naming Convention**: Use the format `YYYY-MM-DD_task-description.md`.
|
|
43
|
+
3. **Content Structure**:
|
|
44
|
+
- Objectives and scope of the task
|
|
45
|
+
- List of subtasks with checkboxes
|
|
46
|
+
- Problems encountered and solutions applied
|
|
47
|
+
- Decisions made and their justification
|
|
48
|
+
|
|
49
|
+
Example:
|
|
50
|
+
|
|
51
|
+
```markdown
|
|
52
|
+
# Authentication Implementation - 2024-08-15
|
|
53
|
+
|
|
54
|
+
## Objectives
|
|
55
|
+
|
|
56
|
+
- Implement email/password login
|
|
57
|
+
- Add OAuth authentication
|
|
58
|
+
- Implement password recovery
|
|
59
|
+
|
|
60
|
+
## Tasks
|
|
61
|
+
|
|
62
|
+
- [x] Create user models and migrations
|
|
63
|
+
- [x] Implement authentication controller
|
|
64
|
+
- [ ] Configure OAuth providers
|
|
65
|
+
- [ ] Implement password recovery emails
|
|
66
|
+
|
|
67
|
+
## Problems and Solutions
|
|
68
|
+
|
|
69
|
+
- Problem: Conflict with session storage
|
|
70
|
+
Solution: Use database-based storage
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## File Management
|
|
74
|
+
|
|
75
|
+
When creating or modifying files in the project:
|
|
76
|
+
|
|
77
|
+
1. **Existence Verification**: Check if the file already exists before creating it.
|
|
78
|
+
2. **Content Preservation**:
|
|
79
|
+
- If it exists and there's no explicit instruction to overwrite, merge changes.
|
|
80
|
+
- Preserve important aspects of the existing file (comments, structure).
|
|
81
|
+
3. **Duplication Prevention**: Avoid creating duplicate files or files with similar functionality.
|
|
82
|
+
4. **Appropriate Location**: Ensure files are created in the correct location according to the project structure.
|
|
83
|
+
|
|
84
|
+
## Code Review
|
|
85
|
+
|
|
86
|
+
1. **Self-Review**: Review your own code before considering it complete.
|
|
87
|
+
2. **Verification Checklist**:
|
|
88
|
+
- Does the code follow project conventions?
|
|
89
|
+
- Is it adequately tested?
|
|
90
|
+
- Is documentation updated?
|
|
91
|
+
- Have edge cases been considered?
|
|
92
|
+
- Is performance acceptable?
|
|
93
|
+
|
|
94
|
+
## Task Completion
|
|
95
|
+
|
|
96
|
+
Consider a task complete only when:
|
|
97
|
+
|
|
98
|
+
1. All automated tests pass.
|
|
99
|
+
2. It is properly documented.
|
|
100
|
+
3. The process log is updated (if applicable).
|
|
101
|
+
4. A code review has been performed.
|
|
102
|
+
5. Changes are ready to be deployed to production.
|
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
---
|
|
2
|
+
projectPath: ./
|
|
3
|
+
cursorPath: .
|
|
4
|
+
description: User credential and test data management rules
|
|
5
|
+
globs: users/**/*,config/**/*,flows/**/*
|
|
6
|
+
alwaysApply: true
|
|
7
|
+
---
|
|
8
|
+
# User Credential Management
|
|
9
|
+
|
|
10
|
+
Best practices for managing test users, credentials, and sensitive test data.
|
|
11
|
+
|
|
12
|
+
## Critical Security Rules
|
|
13
|
+
|
|
14
|
+
### 1. **NEVER commit real credentials**
|
|
15
|
+
```yaml
|
|
16
|
+
# ❌ WRONG: Real credentials in flow file
|
|
17
|
+
- inputText: "real.user@email.com"
|
|
18
|
+
- inputText: "RealPassword123!"
|
|
19
|
+
|
|
20
|
+
# ✅ CORRECT: Use variables
|
|
21
|
+
- inputText: "${EMAIL}"
|
|
22
|
+
- inputText: "${PASSWORD}"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### 2. **Use environment variables**
|
|
26
|
+
```yaml
|
|
27
|
+
# config/users.yaml or flows/users/*.yml
|
|
28
|
+
email: "${EMAIL}" # From environment
|
|
29
|
+
password: "${PASSWORD}" # From environment
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 3. **Keep credentials in gitignored files**
|
|
33
|
+
```gitignore
|
|
34
|
+
# .gitignore should include:
|
|
35
|
+
.env
|
|
36
|
+
.env.local
|
|
37
|
+
.env.*.local
|
|
38
|
+
config/credentials.yaml
|
|
39
|
+
config/users.yaml
|
|
40
|
+
users/*-credentials.yml
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## User Management System
|
|
44
|
+
|
|
45
|
+
### User File Structure
|
|
46
|
+
|
|
47
|
+
```yaml
|
|
48
|
+
# users/socioActivoAbono.yml
|
|
49
|
+
email: "socio.activo.abono@test.bocajuniors.com"
|
|
50
|
+
password: "Test123!Pass"
|
|
51
|
+
attributes:
|
|
52
|
+
tipoSocio: "ACTIVO"
|
|
53
|
+
modalidadPago: "ABONO"
|
|
54
|
+
tieneDeuda: false
|
|
55
|
+
tieneGrupoFamiliar: false
|
|
56
|
+
credentials:
|
|
57
|
+
dni: "12345678"
|
|
58
|
+
numeroSocio: "123456"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### User Types in This Project
|
|
62
|
+
|
|
63
|
+
#### 1. Socio Activo (Active Member)
|
|
64
|
+
```yaml
|
|
65
|
+
# users/socioActivoAbono.yml
|
|
66
|
+
tipoSocio: "ACTIVO"
|
|
67
|
+
modalidadPago: "ABONO"
|
|
68
|
+
tieneAbono: true
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
#### 2. Socio Vitalicio (VIP Lifetime Member)
|
|
72
|
+
```yaml
|
|
73
|
+
# users/socioVitaAbono.yml
|
|
74
|
+
tipoSocio: "VITALICIO"
|
|
75
|
+
modalidadPago: "ABONO"
|
|
76
|
+
tieneAbono: true
|
|
77
|
+
prioridad: "ALTA"
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
#### 3. Socio con Deuda (Member with Debt)
|
|
81
|
+
```yaml
|
|
82
|
+
# users/socioConDeudaPaypal.yml
|
|
83
|
+
tipoSocio: "ACTIVO"
|
|
84
|
+
tieneDeuda: true
|
|
85
|
+
metodoPago: "PAYPAL"
|
|
86
|
+
montoDeuda: 15000
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### 4. Socio Adherente (Associate Member)
|
|
90
|
+
```yaml
|
|
91
|
+
# users/socioAdherenteNo.yml
|
|
92
|
+
tipoSocio: "ADHERENTE"
|
|
93
|
+
tieneAbono: false
|
|
94
|
+
accesoReservas: "WEB_ONLY"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
#### 5. Socio con Grupo Familiar (Member with Family Group)
|
|
98
|
+
```yaml
|
|
99
|
+
# users/socioConGrupoFamiliar.yml
|
|
100
|
+
tipoSocio: "ACTIVO"
|
|
101
|
+
tieneGrupoFamiliar: true
|
|
102
|
+
familiares:
|
|
103
|
+
- nombre: "Familiar 1"
|
|
104
|
+
tipoSocio: "ADHERENTE"
|
|
105
|
+
- nombre: "Familiar 2"
|
|
106
|
+
tipoSocio: "ADHERENTE"
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## User Selection Script
|
|
110
|
+
|
|
111
|
+
### Using get-user.js
|
|
112
|
+
|
|
113
|
+
```javascript
|
|
114
|
+
// scripts/get-user.js
|
|
115
|
+
const fs = require('fs');
|
|
116
|
+
const yaml = require('js-yaml');
|
|
117
|
+
|
|
118
|
+
function getUser(userType) {
|
|
119
|
+
const userFile = `./users/${userType}.yml`;
|
|
120
|
+
if (!fs.existsSync(userFile)) {
|
|
121
|
+
throw new Error(`User file not found: ${userFile}`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const userConfig = yaml.load(fs.readFileSync(userFile, 'utf8'));
|
|
125
|
+
return {
|
|
126
|
+
email: userConfig.email,
|
|
127
|
+
password: userConfig.password,
|
|
128
|
+
attributes: userConfig.attributes
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
module.exports = getUser;
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Usage in Tests
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# Get user credentials for testing
|
|
139
|
+
node scripts/get-user.js socioActivoAbono
|
|
140
|
+
# Output: email and password for test execution
|
|
141
|
+
|
|
142
|
+
# Use in Maestro test
|
|
143
|
+
maestro test \
|
|
144
|
+
--env EMAIL=$(node scripts/get-user.js socioActivoAbono --field email) \
|
|
145
|
+
--env PASSWORD=$(node scripts/get-user.js socioActivoAbono --field password) \
|
|
146
|
+
flows/test.yaml
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## User Sync System
|
|
150
|
+
|
|
151
|
+
### Syncing Users from External Source
|
|
152
|
+
|
|
153
|
+
```javascript
|
|
154
|
+
// scripts/sync-users.js
|
|
155
|
+
// Syncs user configurations from external source (API, database, etc.)
|
|
156
|
+
|
|
157
|
+
const syncUsers = async () => {
|
|
158
|
+
// Fetch users from external source
|
|
159
|
+
const users = await fetchUsersFromAPI();
|
|
160
|
+
|
|
161
|
+
// Save to local user files
|
|
162
|
+
for (const user of users) {
|
|
163
|
+
const userFile = `./users/${user.type}.yml`;
|
|
164
|
+
const userData = {
|
|
165
|
+
email: user.email,
|
|
166
|
+
password: user.password, // Should be test credentials only
|
|
167
|
+
attributes: user.attributes
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
fs.writeFileSync(userFile, yaml.dump(userData));
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Best Practices for User Sync
|
|
176
|
+
|
|
177
|
+
1. **Only sync test credentials**: Never sync production credentials
|
|
178
|
+
2. **Validate user data**: Ensure required fields are present
|
|
179
|
+
3. **Log sync operations**: Track when users were last synced
|
|
180
|
+
4. **Use staging environment**: Sync from staging/test environment only
|
|
181
|
+
|
|
182
|
+
## Credential Rotation
|
|
183
|
+
|
|
184
|
+
### When to Rotate Credentials
|
|
185
|
+
|
|
186
|
+
1. **Regular Schedule**: Every 90 days minimum
|
|
187
|
+
2. **After Team Changes**: When team members leave
|
|
188
|
+
3. **After Security Incidents**: Immediately if credentials compromised
|
|
189
|
+
4. **CI/CD Updates**: When updating CI/CD pipelines
|
|
190
|
+
|
|
191
|
+
### Rotation Process
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
# 1. Generate new credentials in test system
|
|
195
|
+
# 2. Update user files
|
|
196
|
+
# 3. Update CI/CD secrets
|
|
197
|
+
# 4. Notify team
|
|
198
|
+
# 5. Verify all tests still pass
|
|
199
|
+
# 6. Invalidate old credentials
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Environment-Specific Configuration
|
|
203
|
+
|
|
204
|
+
### Development Environment
|
|
205
|
+
```yaml
|
|
206
|
+
# config/users.yaml (for dev)
|
|
207
|
+
defaultUser:
|
|
208
|
+
email: "dev.tester@test.local"
|
|
209
|
+
password: "DevTest123!"
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### CI/CD Environment
|
|
213
|
+
```yaml
|
|
214
|
+
# Use environment variables in CI
|
|
215
|
+
# Set in GitHub Actions secrets / GitLab CI variables
|
|
216
|
+
EMAIL: ${{ secrets.TEST_USER_EMAIL }}
|
|
217
|
+
PASSWORD: ${{ secrets.TEST_USER_PASSWORD }}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Staging Environment
|
|
221
|
+
```yaml
|
|
222
|
+
# config/users-staging.yaml
|
|
223
|
+
defaultUser:
|
|
224
|
+
email: "staging.tester@staging.bocajuniors.com"
|
|
225
|
+
password: "${STAGING_PASSWORD}" # From environment
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Test Data Management
|
|
229
|
+
|
|
230
|
+
### Sensitive Test Data
|
|
231
|
+
|
|
232
|
+
```yaml
|
|
233
|
+
# ❌ WRONG: Hardcoded payment data
|
|
234
|
+
cardNumber: "4111111111111111"
|
|
235
|
+
cvv: "123"
|
|
236
|
+
expiry: "12/25"
|
|
237
|
+
|
|
238
|
+
# ✅ CORRECT: Variables or test data generators
|
|
239
|
+
cardNumber: "${TEST_CARD_NUMBER}"
|
|
240
|
+
cvv: "${TEST_CVV}"
|
|
241
|
+
expiry: "${TEST_EXPIRY}"
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Test Data Generators
|
|
245
|
+
|
|
246
|
+
```javascript
|
|
247
|
+
// utils/test-data-generator.js
|
|
248
|
+
const generateTestCard = () => ({
|
|
249
|
+
number: "4111111111111111", // Test card number
|
|
250
|
+
cvv: "123",
|
|
251
|
+
expiry: "12/25",
|
|
252
|
+
name: "TEST CARDHOLDER"
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
const generateTestUser = (type) => ({
|
|
256
|
+
email: `test.${type}.${Date.now()}@test.local`,
|
|
257
|
+
password: `Test${Math.random().toString(36).slice(-8)}!`,
|
|
258
|
+
type: type
|
|
259
|
+
});
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## User Access Control
|
|
263
|
+
|
|
264
|
+
### User Permission Matrix
|
|
265
|
+
|
|
266
|
+
| User Type | Match Reservations | Payment Methods | Family Group | Priority Access |
|
|
267
|
+
|-----------|-------------------|-----------------|--------------|-----------------|
|
|
268
|
+
| Activo | ✅ Web + Internal | ✅ All | ✅ Yes | ⭐ Normal |
|
|
269
|
+
| Vitalicio | ✅ All + Priority | ✅ All | ✅ Yes | ⭐⭐⭐ High |
|
|
270
|
+
| Adherente | ✅ Web Only | ✅ Limited | ❌ No | ⭐ Low |
|
|
271
|
+
| Con Deuda | ❌ Blocked | ✅ Payment Only | ✅ Yes | ⭐ Low |
|
|
272
|
+
|
|
273
|
+
### Testing Access Control
|
|
274
|
+
|
|
275
|
+
```yaml
|
|
276
|
+
# Test that user can access feature
|
|
277
|
+
- runFlow:
|
|
278
|
+
file: flows/common/login.yaml
|
|
279
|
+
env:
|
|
280
|
+
USER_TYPE: "socioVitalicio"
|
|
281
|
+
- tapOn: "Reservas VIP"
|
|
282
|
+
- assertVisible: "Plateas disponibles"
|
|
283
|
+
|
|
284
|
+
# Test that user CANNOT access feature
|
|
285
|
+
- runFlow:
|
|
286
|
+
file: flows/common/login.yaml
|
|
287
|
+
env:
|
|
288
|
+
USER_TYPE: "socioAdherente"
|
|
289
|
+
- assertNotVisible: "Reservas VIP"
|
|
290
|
+
- assertVisible: "Acceso no autorizado"
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## Credential Storage Best Practices
|
|
294
|
+
|
|
295
|
+
### 1. **Use config/users.yaml as template only**
|
|
296
|
+
```yaml
|
|
297
|
+
# config/users.yaml (committed to repo)
|
|
298
|
+
defaultUser:
|
|
299
|
+
email: "${EMAIL}" # Placeholder
|
|
300
|
+
password: "${PASSWORD}" # Placeholder
|
|
301
|
+
|
|
302
|
+
# config/users.local.yaml (gitignored, actual credentials)
|
|
303
|
+
defaultUser:
|
|
304
|
+
email: "actual.email@test.com"
|
|
305
|
+
password: "ActualPassword123!"
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### 2. **Use .env files for local development**
|
|
309
|
+
```bash
|
|
310
|
+
# .env.local (gitignored)
|
|
311
|
+
TEST_USER_EMAIL=test.user@example.com
|
|
312
|
+
TEST_USER_PASSWORD=TestPassword123!
|
|
313
|
+
ADMIN_USER_EMAIL=admin@example.com
|
|
314
|
+
ADMIN_USER_PASSWORD=AdminPass123!
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### 3. **Use CI/CD secrets for pipelines**
|
|
318
|
+
```yaml
|
|
319
|
+
# .github/workflows/test.yml
|
|
320
|
+
- name: Run Tests
|
|
321
|
+
env:
|
|
322
|
+
EMAIL: ${{ secrets.TEST_USER_EMAIL }}
|
|
323
|
+
PASSWORD: ${{ secrets.TEST_USER_PASSWORD }}
|
|
324
|
+
run: maestro test flows/
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## Audit and Compliance
|
|
328
|
+
|
|
329
|
+
### Logging User Usage
|
|
330
|
+
```javascript
|
|
331
|
+
// Log which user credentials are used in tests
|
|
332
|
+
const logUserAccess = (userType, testName) => {
|
|
333
|
+
console.log(`[${new Date().toISOString()}] Test: ${testName}, User: ${userType}`);
|
|
334
|
+
// Can be extended to write to audit log
|
|
335
|
+
};
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Credential Compliance Checklist
|
|
339
|
+
- [ ] No production credentials in test environment
|
|
340
|
+
- [ ] All credentials are in gitignored files
|
|
341
|
+
- [ ] CI/CD uses secret management
|
|
342
|
+
- [ ] Credentials rotated regularly
|
|
343
|
+
- [ ] Access logs maintained
|
|
344
|
+
- [ ] Team has minimal necessary access
|
|
345
|
+
- [ ] Credentials are encrypted at rest
|
|
346
|
+
|
|
347
|
+
## Emergency Procedures
|
|
348
|
+
|
|
349
|
+
### If Credentials Are Compromised
|
|
350
|
+
|
|
351
|
+
1. **Immediate Actions**:
|
|
352
|
+
```bash
|
|
353
|
+
# 1. Rotate all affected credentials
|
|
354
|
+
# 2. Review access logs
|
|
355
|
+
# 3. Notify security team
|
|
356
|
+
# 4. Update all systems with new credentials
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
2. **Investigation**:
|
|
360
|
+
- Check git history for accidental commits
|
|
361
|
+
- Review CI/CD logs
|
|
362
|
+
- Check for unauthorized access
|
|
363
|
+
- Document incident
|
|
364
|
+
|
|
365
|
+
3. **Prevention**:
|
|
366
|
+
- Enable git hooks to prevent credential commits
|
|
367
|
+
- Use secret scanning tools
|
|
368
|
+
- Educate team on best practices
|
|
369
|
+
|
|
370
|
+
## Summary Checklist
|
|
371
|
+
|
|
372
|
+
Before adding new test user:
|
|
373
|
+
- [ ] User credentials are test-only (not production)
|
|
374
|
+
- [ ] User file follows naming convention
|
|
375
|
+
- [ ] User attributes are documented
|
|
376
|
+
- [ ] Credentials use environment variables where possible
|
|
377
|
+
- [ ] User file is added to .gitignore if contains real credentials
|
|
378
|
+
|
|
379
|
+
Before committing code:
|
|
380
|
+
- [ ] No hardcoded credentials in code
|
|
381
|
+
- [ ] No real emails or passwords visible
|
|
382
|
+
- [ ] Test data uses variables
|
|
383
|
+
- [ ] Sensitive files are gitignored
|
|
384
|
+
- [ ] CI/CD secrets are configured
|
|
385
|
+
|
|
386
|
+
Regular maintenance:
|
|
387
|
+
- [ ] Review user access quarterly
|
|
388
|
+
- [ ] Rotate credentials regularly
|
|
389
|
+
- [ ] Remove unused test users
|
|
390
|
+
- [ ] Audit credential usage
|
|
391
|
+
- [ ] Update documentation
|