tsykvas_rails_template 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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +200 -0
- data/CODE_OF_CONDUCT.md +10 -0
- data/LICENSE.txt +21 -0
- data/README.md +589 -0
- data/Rakefile +17 -0
- data/lib/generators/tsykvas_rails_template/companions/companions_generator.rb +273 -0
- data/lib/generators/tsykvas_rails_template/concept/concept_generator.rb +145 -0
- data/lib/generators/tsykvas_rails_template/concept/templates/component/edit.html.slim.tt +5 -0
- data/lib/generators/tsykvas_rails_template/concept/templates/component/edit.rb.tt +11 -0
- data/lib/generators/tsykvas_rails_template/concept/templates/component/index.html.slim.tt +5 -0
- data/lib/generators/tsykvas_rails_template/concept/templates/component/index.rb.tt +11 -0
- data/lib/generators/tsykvas_rails_template/concept/templates/component/new.html.slim.tt +5 -0
- data/lib/generators/tsykvas_rails_template/concept/templates/component/new.rb.tt +11 -0
- data/lib/generators/tsykvas_rails_template/concept/templates/component/show.html.slim.tt +4 -0
- data/lib/generators/tsykvas_rails_template/concept/templates/component/show.rb.tt +11 -0
- data/lib/generators/tsykvas_rails_template/concept/templates/controller.rb.tt +45 -0
- data/lib/generators/tsykvas_rails_template/concept/templates/operation/create.rb.tt +31 -0
- data/lib/generators/tsykvas_rails_template/concept/templates/operation/destroy.rb.tt +13 -0
- data/lib/generators/tsykvas_rails_template/concept/templates/operation/edit.rb.tt +10 -0
- data/lib/generators/tsykvas_rails_template/concept/templates/operation/index.rb.tt +9 -0
- data/lib/generators/tsykvas_rails_template/concept/templates/operation/new.rb.tt +10 -0
- data/lib/generators/tsykvas_rails_template/concept/templates/operation/show.rb.tt +10 -0
- data/lib/generators/tsykvas_rails_template/concept/templates/operation/update.rb.tt +31 -0
- data/lib/generators/tsykvas_rails_template/install/bootstrap_installer.rb +225 -0
- data/lib/generators/tsykvas_rails_template/install/install_generator.rb +298 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/agents/buddy.md +157 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/agents/code-reviewer.md +117 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/agents/security-reviewer.md +113 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/agents/tech-lead.md +150 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/commands/check.md +51 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/commands/code-review.md +60 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/commands/docs-create.md +102 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/commands/pr-review.md +81 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/commands/pushit.md +160 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/commands/refactor.md +132 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/commands/task-sum.md +47 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/commands/tests.md +67 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/commands/tsykvas-claude.md +262 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/commands/update-docs.md +78 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/commands/update-rules.md +102 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/commands/update-tests.md +135 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/docs/architecture.md +315 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/docs/authentication.md +96 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/docs/background-jobs.md +135 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/docs/code-style.md +101 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/docs/commands.md +34 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/docs/companions.md +128 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/docs/concepts-refactoring.md +194 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/docs/database.md +135 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/docs/deployment.md +138 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/docs/design-system.md +322 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/docs/documentation.md +89 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/docs/forms.md +174 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/docs/i18n.md +165 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/docs/routing-and-namespaces.md +114 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/docs/security.md +122 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/docs/stimulus-controllers.md +166 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/docs/testing-examples.md +180 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/docs/testing.md +117 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/docs/tsykvas_rails_template.md +280 -0
- data/lib/generators/tsykvas_rails_template/install/templates/.claude/docs/ui-components.md +196 -0
- data/lib/generators/tsykvas_rails_template/install/templates/CLAUDE.md.tt +81 -0
- data/lib/generators/tsykvas_rails_template/install/templates/app/concepts/base/component/base.rb +6 -0
- data/lib/generators/tsykvas_rails_template/install/templates/app/concepts/base/operation/base.rb +124 -0
- data/lib/generators/tsykvas_rails_template/install/templates/app/concepts/base/operation/result.rb +56 -0
- data/lib/generators/tsykvas_rails_template/install/templates/app/concepts/home/component/index.html.slim +49 -0
- data/lib/generators/tsykvas_rails_template/install/templates/app/concepts/home/component/index.rb +11 -0
- data/lib/generators/tsykvas_rails_template/install/templates/app/concepts/home/operation/index.rb +17 -0
- data/lib/generators/tsykvas_rails_template/install/templates/app/controllers/concerns/operations_methods.rb +148 -0
- data/lib/generators/tsykvas_rails_template/install/templates/app/controllers/home_controller.rb +10 -0
- data/lib/generators/tsykvas_rails_template/install/templates/app/policies/application_policy.rb +33 -0
- data/lib/generators/tsykvas_rails_template/install/templates/app/policies/home_policy.rb +8 -0
- data/lib/tasks/tsykvas.rake +11 -0
- data/lib/tsykvas_rails_template/probe.rb +236 -0
- data/lib/tsykvas_rails_template/railtie.rb +13 -0
- data/lib/tsykvas_rails_template/version.rb +5 -0
- data/lib/tsykvas_rails_template.rb +18 -0
- metadata +183 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
Review a GitHub Pull Request using the project's code review standards.
|
|
2
|
+
|
|
3
|
+
## Usage
|
|
4
|
+
|
|
5
|
+
`/pr-review <PR_NUMBER_OR_URL>`
|
|
6
|
+
|
|
7
|
+
Examples:
|
|
8
|
+
- `/pr-review 123`
|
|
9
|
+
- `/pr-review https://github.com/org/repo/pull/123`
|
|
10
|
+
|
|
11
|
+
## Steps
|
|
12
|
+
|
|
13
|
+
1. Extract the PR number from the argument (strip URL if needed).
|
|
14
|
+
|
|
15
|
+
2. Fetch PR metadata:
|
|
16
|
+
```
|
|
17
|
+
gh pr view <number> --json number,title,body,author,baseRefName,headRefName,labels,additions,deletions,changedFiles
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
3. Fetch list of changed files:
|
|
21
|
+
```
|
|
22
|
+
gh pr diff <number> --name-only
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
4. Launch **three agents in parallel** using the Agent tool, giving each the PR metadata and list of changed files — let them read the files and diff themselves:
|
|
26
|
+
|
|
27
|
+
**Agent 1 — code-reviewer** (subagent_type: `code-reviewer`)
|
|
28
|
+
Prompt: "Review the changes in PR #<number> '<title>'. Changed files: [list]. Use `gh pr diff <number>`, Read, Glob, Grep to read the files and understand what changed. Focus on Concepts Pattern compliance, code style, and best practices."
|
|
29
|
+
|
|
30
|
+
**Agent 2 — security-reviewer** (subagent_type: `security-reviewer`)
|
|
31
|
+
Prompt: "Security audit the changes in PR #<number> '<title>'. Changed files: [list]. Use `gh pr diff <number>`, Read, Glob, Grep to read the files and understand what changed."
|
|
32
|
+
|
|
33
|
+
**Agent 3 — tech-lead** (subagent_type: `tech-lead`)
|
|
34
|
+
Prompt: "Pre-PR architectural review of PR #<number> '<title>' by <author>. Base: <baseRef> ← <headRef>. PR description: <body>. Changed files: [list]. Use `gh pr diff <number>`, Read, Glob, Grep to read the files and understand what changed."
|
|
35
|
+
|
|
36
|
+
5. Collect results from all three agents and present a unified report.
|
|
37
|
+
|
|
38
|
+
## Output format
|
|
39
|
+
|
|
40
|
+
Present the final report in **English** with the following structure:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
# PR Review: #<number> — <title>
|
|
44
|
+
|
|
45
|
+
**Author:** <author> | **Branch:** <headRef> → <baseRef>
|
|
46
|
+
**Changes:** +<additions> / -<deletions> across <changedFiles> files
|
|
47
|
+
|
|
48
|
+
## Changed Files
|
|
49
|
+
<list of changed files with a brief one-line description of what changed in each>
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Code Review (Concepts Pattern, style, best practices)
|
|
54
|
+
<output from code-reviewer agent>
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Security
|
|
59
|
+
<output from security-reviewer agent>
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Architecture & Assessment
|
|
64
|
+
<output from tech-lead agent>
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Summary
|
|
69
|
+
|
|
70
|
+
**Merge readiness:** ✅ Ready / ⚠️ Needs fixes / 🔴 Blocker
|
|
71
|
+
|
|
72
|
+
<3–5 bullet points: critical blockers, required fixes, optional improvements>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Rules
|
|
76
|
+
|
|
77
|
+
- If no PR number is provided, print usage instructions and stop.
|
|
78
|
+
- If `gh` returns an error (not authenticated, PR not found), report it clearly and stop.
|
|
79
|
+
- Do not check out the branch or modify the working tree.
|
|
80
|
+
- Skip locale files unless a key is missing, duplicated, or used inconsistently.
|
|
81
|
+
- Every finding must include the file path and line number.
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
Pre-flight checks, commit, and push to current branch on GitHub. Validates nothing sensitive is committed, runs full health checks, then commits and pushes.
|
|
2
|
+
|
|
3
|
+
Five phases: **Update docs → Update rules → Safety scan → Health checks → Commit & push**. Stop and ask the user if any phase finds problems.
|
|
4
|
+
|
|
5
|
+
## Phase 0a: Update documentation
|
|
6
|
+
|
|
7
|
+
Run the `/update-docs` command first. This checks whether documentation in `docs/` (project root) needs updating based on code changes. Follow its full flow (present findings, ask for confirmation, update if approved).
|
|
8
|
+
|
|
9
|
+
## Phase 0b: Update rules
|
|
10
|
+
|
|
11
|
+
Run the `/update-rules` command. This checks whether `.claude/docs/` or `CLAUDE.md` need updating based on changes to base classes. Follow its full flow (present proposed changes, require explicit confirmation before any edits).
|
|
12
|
+
|
|
13
|
+
## Phase 1: Safety scan
|
|
14
|
+
|
|
15
|
+
Check that we are not committing something we shouldn't.
|
|
16
|
+
|
|
17
|
+
### 1a. Scan staged and unstaged changes for sensitive files
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
git status --short 2>&1
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Look for files that should NOT be in git:
|
|
24
|
+
|
|
25
|
+
| Pattern | Why |
|
|
26
|
+
|---------|-----|
|
|
27
|
+
| `.env`, `.env.*` (not `.env.example`) | Secrets, API keys |
|
|
28
|
+
| `*.key`, `*.pem`, `*.crt`, `*.p12` | Private keys / certs |
|
|
29
|
+
| `credentials.yml.enc` changes without `*.key` in gitignore | Encrypted credentials |
|
|
30
|
+
| `config/master.key` | Rails master key |
|
|
31
|
+
| `*.sqlite3`, `*.sqlite3-*` | Local databases |
|
|
32
|
+
| `node_modules/`, `vendor/bundle/` | Dependencies |
|
|
33
|
+
| `.idea/` (non-shared config), `*.iml` | IDE-specific files |
|
|
34
|
+
| `coverage/` | Test coverage reports |
|
|
35
|
+
| `/storage/*` | Uploaded files |
|
|
36
|
+
| `/log/*`, `/tmp/*` | Logs and temp files |
|
|
37
|
+
| `*.dump`, `*.sql` | Database dumps |
|
|
38
|
+
| Files containing hardcoded tokens/passwords | Secrets in code |
|
|
39
|
+
|
|
40
|
+
Also check:
|
|
41
|
+
```bash
|
|
42
|
+
git diff --cached --name-only 2>&1
|
|
43
|
+
git diff --name-only 2>&1
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 1b. Grep for accidental secrets in changed files
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
git diff -U0 | grep -iE '(api_key|secret|password|token|private_key)\s*[:=]' 2>&1
|
|
50
|
+
git diff --cached -U0 | grep -iE '(api_key|secret|password|token|private_key)\s*[:=]' 2>&1
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 1c. Check if .gitignore is missing common patterns
|
|
54
|
+
|
|
55
|
+
Verify `.gitignore` covers: `.env*`, `*.key`, `/log/*`, `/tmp/*`, `/storage/*`, `/coverage`, `/public/assets`.
|
|
56
|
+
|
|
57
|
+
### If problems found
|
|
58
|
+
|
|
59
|
+
Show a table:
|
|
60
|
+
|
|
61
|
+
| File / Pattern | Problem | Suggestion |
|
|
62
|
+
|----------------|---------|------------|
|
|
63
|
+
| ... | ... | ... |
|
|
64
|
+
|
|
65
|
+
Ask:
|
|
66
|
+
> Found N safety issue(s). Fix them?
|
|
67
|
+
> 1. Yes, fix (add to .gitignore / unstage / remove)
|
|
68
|
+
> 2. No, continue anyway
|
|
69
|
+
> 3. Abort
|
|
70
|
+
|
|
71
|
+
Wait for response. Fix if asked, abort if asked, or continue.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Phase 2: Health checks
|
|
76
|
+
|
|
77
|
+
Run the full check suite as defined in `/check`:
|
|
78
|
+
|
|
79
|
+
1. `bin/rails zeitwerk:check 2>&1`
|
|
80
|
+
2. `bundle exec rspec --format progress 2>&1`
|
|
81
|
+
3. `bin/rubocop --format simple 2>&1`
|
|
82
|
+
|
|
83
|
+
Run ALL checks, never stop early.
|
|
84
|
+
|
|
85
|
+
### If problems found
|
|
86
|
+
|
|
87
|
+
Show the summary table:
|
|
88
|
+
|
|
89
|
+
| Check | Status | Issues |
|
|
90
|
+
|-------|--------|--------|
|
|
91
|
+
| ... | ... | ... |
|
|
92
|
+
|
|
93
|
+
Then show issue details and ask:
|
|
94
|
+
> Found N issue(s). Fix them before pushing?
|
|
95
|
+
> 1. Yes, fix all
|
|
96
|
+
> 2. No, push anyway
|
|
97
|
+
> 3. Abort
|
|
98
|
+
|
|
99
|
+
Wait for response. If yes — fix issues, re-run failing checks to confirm, then continue.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Phase 3: Commit & push
|
|
104
|
+
|
|
105
|
+
### 3a. Stage changes
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
git add -A
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Review what's being committed:
|
|
112
|
+
```bash
|
|
113
|
+
git diff --cached --stat 2>&1
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### 3b. Create commit
|
|
117
|
+
|
|
118
|
+
- Write a concise 1-sentence commit message that describes WHAT changed and WHY
|
|
119
|
+
- Use imperative mood ("Add...", "Fix...", "Refactor...", "Update...")
|
|
120
|
+
- Keep under 72 characters
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
git commit -m "$(cat <<'EOF'
|
|
124
|
+
Your commit message here
|
|
125
|
+
|
|
126
|
+
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|
127
|
+
EOF
|
|
128
|
+
)"
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### 3c. Push to current branch
|
|
132
|
+
|
|
133
|
+
Determine the current branch:
|
|
134
|
+
```bash
|
|
135
|
+
git branch --show-current 2>&1
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Push:
|
|
139
|
+
```bash
|
|
140
|
+
git push origin HEAD 2>&1
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### If push fails
|
|
144
|
+
|
|
145
|
+
- **No upstream**: run `git push -u origin HEAD 2>&1`
|
|
146
|
+
- **Rejected (non-fast-forward)**: try `git pull --rebase origin <branch> 2>&1`, resolve conflicts if any, then push again
|
|
147
|
+
- **Merge conflict during rebase**: show the conflicts and ask for guidance
|
|
148
|
+
- **Needs force push**: **NEVER force push automatically**. Show the situation and ask:
|
|
149
|
+
> Push was rejected. Force push with `--force-with-lease`?
|
|
150
|
+
> 1. Yes
|
|
151
|
+
> 2. No, abort
|
|
152
|
+
|
|
153
|
+
### 3d. Confirm
|
|
154
|
+
|
|
155
|
+
Show final status:
|
|
156
|
+
```
|
|
157
|
+
Pushed to <branch> → <remote-url>
|
|
158
|
+
Commit: <short-hash> <message>
|
|
159
|
+
Files changed: N
|
|
160
|
+
```
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
Refactor the provided files following the project's architecture and clean code principles.
|
|
2
|
+
|
|
3
|
+
## Input
|
|
4
|
+
|
|
5
|
+
Files to refactor: $ARGUMENTS
|
|
6
|
+
|
|
7
|
+
If no files are provided, ask the user which files they want to refactor.
|
|
8
|
+
|
|
9
|
+
## Steps
|
|
10
|
+
|
|
11
|
+
### 1. Read and understand
|
|
12
|
+
|
|
13
|
+
Read every file listed in `$ARGUMENTS`. Also read any closely related files needed for full context:
|
|
14
|
+
|
|
15
|
+
- The `.slim` template when refactoring a component `.rb`
|
|
16
|
+
- The operation when refactoring the component that consumes it
|
|
17
|
+
- **Sibling files of the same type** (e.g. if refactoring `users_table.rb`, also read `companies_table.rb`) — they often share duplicated logic that should be extracted together
|
|
18
|
+
|
|
19
|
+
### 2. Analyse for issues
|
|
20
|
+
|
|
21
|
+
Before writing any code, identify all issues in the files:
|
|
22
|
+
|
|
23
|
+
**Clean code:**
|
|
24
|
+
- Methods longer than 30 lines or conceptually doing more than one thing
|
|
25
|
+
- Classes longer than 150 lines — investigate whether the class can be split
|
|
26
|
+
- Logic that can be extracted into a well-named private method
|
|
27
|
+
- Repeated expressions or patterns — both within the file **and across sibling files**. When logic is duplicated across files, extract it (a shared concern, a helper class, or a method on `Base::Component::Base`)
|
|
28
|
+
- Variables or methods with unclear names
|
|
29
|
+
- Deep nesting (more than 2–3 levels) that can be flattened
|
|
30
|
+
- Long parameter lists — group with a value object or keyword args
|
|
31
|
+
- Magic constants — extract to a named constant
|
|
32
|
+
- Comments that explain *what* instead of *why* (replace with expressive code)
|
|
33
|
+
|
|
34
|
+
**Ruby / Rails style (per `.claude/docs/code-style.md`):**
|
|
35
|
+
- Missing `# frozen_string_literal: true`
|
|
36
|
+
- Use of `t()` shorthand instead of `I18n.t('full.key')` in components and operations
|
|
37
|
+
- `DateTime.parse(...)` — replace with `Time.zone.parse(...)`
|
|
38
|
+
- Missing trailing commas in multi-line arrays and hashes
|
|
39
|
+
- Missing locale keys in `config/locales/<your-default>.yml` and `config/locales/<other>.yml`
|
|
40
|
+
- `rubocop:disable` annotations — investigate each one; fix the underlying issue if possible
|
|
41
|
+
|
|
42
|
+
**Concepts Pattern (per `.claude/docs/architecture.md`):**
|
|
43
|
+
- Components that fetch data (must be pure presentation — only `initialize` + helpers)
|
|
44
|
+
- Operations that contain presentation logic
|
|
45
|
+
- Missing `authorize!` / `policy_scope` / `skip_authorize` in operations
|
|
46
|
+
- Non-compact class notation (nested modules instead of `class Feature::Op::Action`)
|
|
47
|
+
- Controllers that do more than `endpoint Op, Component`
|
|
48
|
+
- Index operations missing `Base::Operation::Sortable` allowlist for sorting params
|
|
49
|
+
|
|
50
|
+
**ViewComponent specifics:**
|
|
51
|
+
- `call`-style components: long `call` methods that mix column definitions with logic — extract cell helpers
|
|
52
|
+
- Duplicated column/cell rendering logic across table components
|
|
53
|
+
- `tag.div`/`tag.span` chains that can be extracted into named helper methods
|
|
54
|
+
- Buttons not using `Base::Component::Btn` (all buttons must use it with a valid `type:`)
|
|
55
|
+
- Multiple buttons in a table cell not wrapped in `safe_join([render(...), ...])`
|
|
56
|
+
|
|
57
|
+
**Stimulus controllers (per `.claude/docs/stimulus-controllers.md`):**
|
|
58
|
+
- Document-level event listeners not using arrow-function class fields (or properly stored bound references)
|
|
59
|
+
- Missing `disconnect()` cleanup for any listener added in `connect()`
|
|
60
|
+
- `.bind(this)` used in `connect()` without storing the reference for later removal
|
|
61
|
+
- Controller doing more than one responsibility — split into focused controllers
|
|
62
|
+
|
|
63
|
+
### 3. Refactor
|
|
64
|
+
|
|
65
|
+
Apply all improvements found in step 2. Rules:
|
|
66
|
+
|
|
67
|
+
- **Preserve all existing behaviour exactly** — this is a refactor, not a rewrite
|
|
68
|
+
- **Extract private methods** for any logic block that has a clear single responsibility or is used more than once
|
|
69
|
+
- **Name methods after what they return or do**, not how they do it (`role_badge` not `build_span_with_class`)
|
|
70
|
+
- **Keep public interface identical** — same `initialize` signature, same `call` output
|
|
71
|
+
- **One concern per method** — data transformation, formatting, and rendering should not mix
|
|
72
|
+
- **Slim templates**: keep logic minimal; move Ruby expressions into the component `.rb`
|
|
73
|
+
- **Operations**: split `perform!` into private steps when it has more than 3–4 distinct phases
|
|
74
|
+
- **Shared logic across files**: when the same method exists in two or more files, extract it once and call it from both — do not leave duplicates
|
|
75
|
+
- **OpenStruct keys**: if a key in `self.model = ::OpenStruct.new(...)` is never read by the component, remove it from both the operation and the component `initialize`
|
|
76
|
+
- Do NOT add features, change behaviour, or "improve" things that were not identified as issues
|
|
77
|
+
- Do NOT add docstrings or inline comments unless the logic is genuinely non-obvious
|
|
78
|
+
|
|
79
|
+
### 4. Update locales if needed
|
|
80
|
+
|
|
81
|
+
If you added or renamed any `I18n.t()` call, update both:
|
|
82
|
+
- `config/locales/<your-default>.yml`
|
|
83
|
+
- `config/locales/<other>.yml`
|
|
84
|
+
|
|
85
|
+
### 5. Run specs for refactored files
|
|
86
|
+
|
|
87
|
+
For each `.rb` file refactored, check whether a corresponding spec exists by mirroring the path under `spec/`. If a spec exists, run it:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
bundle exec rspec <spec_file_path>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
If tests fail:
|
|
94
|
+
- **Caused by our changes** (e.g. renamed a private method that was tested directly, changed a return value) — fix the source code or the spec to match the new structure while preserving the intent of the test
|
|
95
|
+
- **Pre-existing failures unrelated to our changes** — report them but do not fix; note them in the output as "pre-existing"
|
|
96
|
+
|
|
97
|
+
Do NOT delete or weaken tests to make them pass.
|
|
98
|
+
|
|
99
|
+
### 6. Validate
|
|
100
|
+
|
|
101
|
+
Run in order and fix any failures before reporting:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
bin/rails zeitwerk:check
|
|
105
|
+
bin/rubocop -A
|
|
106
|
+
bin/rubocop
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Run `-A` (autocorrect) first to fix all auto-correctable offenses, then run plain `rubocop` to address any remaining issues manually.
|
|
110
|
+
|
|
111
|
+
## Output format
|
|
112
|
+
|
|
113
|
+
After completing the refactor, report:
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
## Refactored files
|
|
117
|
+
<list of files changed>
|
|
118
|
+
|
|
119
|
+
## What changed
|
|
120
|
+
<for each file: bullet list of specific changes made and why>
|
|
121
|
+
|
|
122
|
+
## Validation
|
|
123
|
+
<result of zeitwerk / rubocop>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Rules
|
|
127
|
+
|
|
128
|
+
- Never skip the validation step.
|
|
129
|
+
- If a file is already clean and well-structured, say so and make no changes.
|
|
130
|
+
- If a refactor would require changing a public API used by other files, read those callers first and update them too.
|
|
131
|
+
- Prefer many small focused private methods over few large ones.
|
|
132
|
+
- The final code must be easier to read than the original — that is the only success criterion.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
Generate a user-facing release notes Markdown file based on the current git changes in this branch.
|
|
2
|
+
|
|
3
|
+
## Steps
|
|
4
|
+
|
|
5
|
+
1. Run `git log main..HEAD --oneline` to see all commits in the current branch.
|
|
6
|
+
|
|
7
|
+
2. Run `git diff main...HEAD --stat` to get a high-level overview of changed files.
|
|
8
|
+
|
|
9
|
+
3. Run `git diff main...HEAD` to read the full diff.
|
|
10
|
+
|
|
11
|
+
4. Read any key changed files (components, operations, views, locale files) to understand *what* the feature actually does from the user's perspective.
|
|
12
|
+
|
|
13
|
+
5. Determine a short, descriptive filename for the release notes based on the feature, e.g. `RELEASE_NOTES_<FEATURE_NAME>.md`.
|
|
14
|
+
|
|
15
|
+
6. Write the file to the **project root** (`<filename>.md`).
|
|
16
|
+
|
|
17
|
+
## Output format
|
|
18
|
+
|
|
19
|
+
The file must be written in **English** and follow this structure:
|
|
20
|
+
|
|
21
|
+
```markdown
|
|
22
|
+
# <Feature Title>
|
|
23
|
+
|
|
24
|
+
## What's New
|
|
25
|
+
|
|
26
|
+
<1–3 sentences describing the new feature or improvement and the problem it solves.>
|
|
27
|
+
|
|
28
|
+
## How It Works
|
|
29
|
+
|
|
30
|
+
<Step-by-step or bullet-point explanation of the feature from the user perspective.>
|
|
31
|
+
|
|
32
|
+
## Where to Find It
|
|
33
|
+
|
|
34
|
+
<Tell the user where in the UI this appears and how to access it.>
|
|
35
|
+
|
|
36
|
+
## Notes
|
|
37
|
+
|
|
38
|
+
<Optional. Any caveats, edge cases, or useful context for the user.>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Rules
|
|
42
|
+
|
|
43
|
+
- Write for **end users**, not developers — no class names, no file paths, no framework terms.
|
|
44
|
+
- Focus on **what changed** and **why it matters**, not how it was implemented.
|
|
45
|
+
- If the branch contains multiple unrelated changes, create one file that covers all of them in separate sections.
|
|
46
|
+
- Keep the tone clear, concise, and professional.
|
|
47
|
+
- Do not include a "Notes" section if there is nothing meaningful to say.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
Run RSpec tests and RuboCop linting, check test coverage for uncommitted changes, then automatically fix any issues found.
|
|
2
|
+
|
|
3
|
+
Follow the project test conventions defined in: `.claude/docs/testing.md` and `.claude/docs/testing-examples.md`.
|
|
4
|
+
|
|
5
|
+
## Step 0: Check test coverage for uncommitted changes
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git diff --name-only HEAD 2>&1
|
|
9
|
+
git diff --name-only --cached HEAD 2>&1
|
|
10
|
+
git ls-files --others --exclude-standard 2>&1
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
From the combined output, find all `.rb` files that contain logic (controllers, operations, components, models, policies, services — skip empty classes, pure config, migrations, and files with no methods).
|
|
14
|
+
|
|
15
|
+
For each such file, check if a corresponding spec exists:
|
|
16
|
+
|
|
17
|
+
- `app/concepts/admin/user/operation/index.rb` → `spec/concepts/admin/user/operation/index_spec.rb`
|
|
18
|
+
- `app/controllers/admin/users_controller.rb` → `spec/controllers/admin/users_controller_spec.rb` or `spec/requests/admin/users_spec.rb`
|
|
19
|
+
- `app/policies/crm/company_policy.rb` → `spec/policies/crm/company_policy_spec.rb`
|
|
20
|
+
- `app/models/user.rb` → `spec/models/user_spec.rb`
|
|
21
|
+
- `app/concepts/admin/user/component/users_table.rb` → `spec/concepts/admin/user/component/users_table_spec.rb`
|
|
22
|
+
|
|
23
|
+
If a spec file is **missing** — create it following conventions in `.claude/docs/testing.md` and `.claude/docs/testing-examples.md`.
|
|
24
|
+
If a spec file **exists** but doesn't cover the new/changed logic — update it to cover the changes.
|
|
25
|
+
|
|
26
|
+
**Important:** For each changed `.rb` file, read the actual diff (`git diff HEAD -- <file>`) and the corresponding spec. Verify that every new/changed public method, conditional branch, and business logic path is covered by tests. Don't just check that a spec file exists — check that it tests the new code.
|
|
27
|
+
|
|
28
|
+
**Skip testing for:** Component `.rb` files that only contain parameter initialization (no business logic, no methods beyond `initialize`). These are pure data-passing wrappers and don't need specs.
|
|
29
|
+
|
|
30
|
+
## Step 1: RSpec
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
bundle exec rspec --format progress 2>&1
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
If there are failures:
|
|
37
|
+
1. Read each failing spec and the corresponding source file
|
|
38
|
+
2. Determine whether the bug is in the test or in the source code
|
|
39
|
+
3. Fix it
|
|
40
|
+
4. Re-run only the fixed specs to confirm: `bundle exec rspec <file>:<line> 2>&1`
|
|
41
|
+
|
|
42
|
+
## Step 2: RuboCop
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
bin/rubocop --format simple 2>&1
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
If there are offenses:
|
|
49
|
+
1. Auto-correct what's safe: `bin/rubocop -A 2>&1`
|
|
50
|
+
2. If offenses remain, fix them manually
|
|
51
|
+
3. Re-run rubocop to confirm: `bin/rubocop --format simple 2>&1`
|
|
52
|
+
|
|
53
|
+
## Step 3: Confirm
|
|
54
|
+
|
|
55
|
+
After fixing, re-run both to make sure nothing is broken:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
bundle exec rspec --format progress 2>&1
|
|
59
|
+
bin/rubocop --format simple 2>&1
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Report final status:
|
|
63
|
+
- **RSpec**: X examples, Y failures, Z pending
|
|
64
|
+
- **RuboCop**: X offenses / no offenses
|
|
65
|
+
|
|
66
|
+
If everything passes — just say so.
|
|
67
|
+
If something still fails after your fix attempts — show what's left and ask for guidance.
|