rails-kompot 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 +13 -0
- data/LICENSE.txt +21 -0
- data/README.md +98 -0
- data/Rakefile +4 -0
- data/exe/rails-kompot +91 -0
- data/lib/rails/kompot/version.rb +7 -0
- data/lib/rails/kompot.rb +10 -0
- data/sig/rails/kompot.rbs +6 -0
- data/templates/.claude/commands/add-tests.md +22 -0
- data/templates/.claude/commands/code-coverage.md +26 -0
- data/templates/.claude/commands/commit.md +29 -0
- data/templates/.claude/commands/deliver.md +23 -0
- data/templates/.claude/commands/docs.md +122 -0
- data/templates/.claude/commands/fix.md +23 -0
- data/templates/.claude/commands/lint.md +28 -0
- data/templates/.claude/commands/review-pr.md +35 -0
- data/templates/.rubocop.yml +7 -0
- data/templates/CLAUDE.md +73 -0
- metadata +86 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: ce2101caab873f356ff63b3262ae0b1a7e88b616376acc10c5c9853be7dc8861
|
|
4
|
+
data.tar.gz: b03b947969c3eb99899c611485d3b4677716117db1ecda2c5edd35a7c8228001
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 8ffa3135b12e83c99298c1f4822363f1712cfe6abf29ca5d47f8de5aea342bf2fc99ce9af750e48dae3d5b5bb3b7dfd52c44d85b0a6e0eec4720851b7ad0e0a9
|
|
7
|
+
data.tar.gz: 866b22ee5d2e925234a8ce4583de9605dab28ede63f436009563f9d942b698c7189470b74dfe8eafeb0c822f03b1b468ff2d80eb2da1a48d89d90ece666d07b5
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2026-03-02
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Initial release
|
|
13
|
+
- CLI wrapper around `rails new` with sensible defaults: PostgreSQL, API-only, minimal, no test framework
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Anatolii Kryvishyn
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# rails-kompot
|
|
2
|
+
|
|
3
|
+
A CLI wrapper around `rails new` that bootstraps a production-ready API-only Rails application with testing, linting, and Claude Code skills pre-configured.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
gem install rails-kompot
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
rails-kompot new my_app
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
This creates a new Rails app configured for:
|
|
18
|
+
|
|
19
|
+
- **PostgreSQL** — primary database
|
|
20
|
+
- **API-only mode** — no views, assets, or browser middleware
|
|
21
|
+
- **Minimal footprint** — only essential Rails components loaded
|
|
22
|
+
|
|
23
|
+
## What you get
|
|
24
|
+
|
|
25
|
+
### Gems
|
|
26
|
+
|
|
27
|
+
| Gem | Purpose |
|
|
28
|
+
|-----|---------|
|
|
29
|
+
| `rspec-rails` | Test framework |
|
|
30
|
+
| `factory_bot_rails` | Test factories |
|
|
31
|
+
| `rubocop` + `rubocop-rails` + `rubocop-rspec` | Linting and style enforcement |
|
|
32
|
+
| `test-prof` | Test profiling (FPROF, `let_it_be`, `before_all`) |
|
|
33
|
+
| `simplecov` | Code coverage reporting |
|
|
34
|
+
| `bullet` | N+1 query detection in development |
|
|
35
|
+
|
|
36
|
+
### Configuration
|
|
37
|
+
|
|
38
|
+
- **`.rubocop.yml`** — pre-configured with Rails and RSpec cops
|
|
39
|
+
- **SimpleCov** — configured in `spec/spec_helper.rb` with an 80% minimum coverage threshold
|
|
40
|
+
- **Bullet** — enabled in `config/environments/development.rb` with Rails logger output
|
|
41
|
+
|
|
42
|
+
### Claude skills
|
|
43
|
+
|
|
44
|
+
The generated app includes 8 custom Claude Code slash commands in `.claude/commands/`:
|
|
45
|
+
|
|
46
|
+
| Skill | Description |
|
|
47
|
+
|-------|-------------|
|
|
48
|
+
| `/lint` | Run RuboCop on changed files and auto-correct fixable offenses |
|
|
49
|
+
| `/review-pr` | Diff current branch against main; review for quality, N+1s, missing specs, and type consistency |
|
|
50
|
+
| `/fix` | Diagnose and fix a failing test, RuboCop offense, or error message |
|
|
51
|
+
| `/code-coverage` | Run RSpec, parse SimpleCov output, and suggest specs for under-covered files |
|
|
52
|
+
| `/add-tests` | Generate RSpec unit specs for given source files using test-prof conventions |
|
|
53
|
+
| `/commit` | Analyze changes and create a conventional commit message |
|
|
54
|
+
| `/docs` | Generate or update `docs/` markdown for given `app/` source files |
|
|
55
|
+
| `/deliver` | Run all quality gates in a loop until green, then commit |
|
|
56
|
+
|
|
57
|
+
### `/docs` skill
|
|
58
|
+
|
|
59
|
+
`/docs` mirrors your `app/` directory into `docs/` as structured markdown. For each source file you pass it:
|
|
60
|
+
|
|
61
|
+
1. Reads the class/module and infers method input/output types from signatures, defaults, guard clauses, return expressions, and `db/schema.rb`
|
|
62
|
+
2. Greps the codebase for callers to identify business flows
|
|
63
|
+
3. Creates or updates `docs/<path>.md` — preserving any manually-added notes while refreshing auto-generated sections
|
|
64
|
+
|
|
65
|
+
Example: `/docs app/models/user.rb app/services/payment_processor.rb`
|
|
66
|
+
|
|
67
|
+
### `/deliver` workflow
|
|
68
|
+
|
|
69
|
+
`/deliver` is a one-command quality gate loop:
|
|
70
|
+
|
|
71
|
+
1. **Tests + FPROF** — runs `FPROF=1 bundle exec rspec`; fixes failures; refactors excessive DB record creation to use `let_it_be`/`before_all`
|
|
72
|
+
2. **Coverage** — generates a fresh SimpleCov report and runs `/code-coverage` to add missing specs until the 80% threshold is met
|
|
73
|
+
3. **Lint** — runs `/lint` to auto-correct and fix all RuboCop offenses
|
|
74
|
+
4. **Code review** — runs `/review-pr` and fixes every blocker
|
|
75
|
+
5. **Docs** — runs `/docs` on all changed `app/` files to create or update their `docs/` markdown
|
|
76
|
+
6. **Final verification** — re-runs tests and RuboCop; returns to the relevant step if anything fails
|
|
77
|
+
7. **Commit** — runs `/commit` to create a conventional commit
|
|
78
|
+
|
|
79
|
+
You make code changes, then run `/deliver` — Claude handles the rest.
|
|
80
|
+
|
|
81
|
+
## Requirements
|
|
82
|
+
|
|
83
|
+
- Ruby >= 3.0
|
|
84
|
+
- Rails (railties) >= 7.0
|
|
85
|
+
|
|
86
|
+
## Development
|
|
87
|
+
|
|
88
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt.
|
|
89
|
+
|
|
90
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
91
|
+
|
|
92
|
+
## Contributing
|
|
93
|
+
|
|
94
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/kompoteria/rails-kompot. Please open an issue before submitting a pull request for significant changes.
|
|
95
|
+
|
|
96
|
+
## License
|
|
97
|
+
|
|
98
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/exe/rails-kompot
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "fileutils"
|
|
5
|
+
|
|
6
|
+
PRESET_FLAGS = %w[-d postgresql -T --api --minimal].freeze
|
|
7
|
+
|
|
8
|
+
def usage
|
|
9
|
+
<<~USAGE
|
|
10
|
+
Usage: rails-kompot new <app_name_or_path> [extra rails options]
|
|
11
|
+
|
|
12
|
+
Creates a new Rails API application with preset flags:
|
|
13
|
+
#{PRESET_FLAGS.join(" ")}
|
|
14
|
+
|
|
15
|
+
Examples:
|
|
16
|
+
rails-kompot new my_app
|
|
17
|
+
rails-kompot new .
|
|
18
|
+
rails-kompot new my_app --skip-git
|
|
19
|
+
USAGE
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
command = ARGV[0]
|
|
23
|
+
|
|
24
|
+
if command.nil? || command == "--help" || command == "-h"
|
|
25
|
+
puts usage
|
|
26
|
+
exit command.nil? ? 1 : 0
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
unless command == "new"
|
|
30
|
+
warn "Unknown command: #{command}"
|
|
31
|
+
warn usage
|
|
32
|
+
exit 1
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
app_name = ARGV[1]
|
|
36
|
+
|
|
37
|
+
if app_name.nil?
|
|
38
|
+
warn "Error: missing app name or path\n\n"
|
|
39
|
+
warn usage
|
|
40
|
+
exit 1
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
extra_args = ARGV[2..]
|
|
44
|
+
|
|
45
|
+
cmd = ["rails", "new", app_name, *PRESET_FLAGS, *extra_args]
|
|
46
|
+
puts "Running: #{cmd.join(" ")}"
|
|
47
|
+
system(*cmd) || abort("rails new failed")
|
|
48
|
+
|
|
49
|
+
app_dir = app_name == "." ? Dir.pwd : File.expand_path(app_name)
|
|
50
|
+
templates_dir = File.join(__dir__, "..", "templates")
|
|
51
|
+
|
|
52
|
+
Dir.glob("#{templates_dir}/**/*", File::FNM_DOTMATCH).each do |src|
|
|
53
|
+
next if File.directory?(src)
|
|
54
|
+
relative = src.delete_prefix("#{templates_dir}/")
|
|
55
|
+
dest = File.join(app_dir, relative)
|
|
56
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
|
57
|
+
FileUtils.cp(src, dest)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
gemfile_path = File.join(app_dir, "Gemfile")
|
|
61
|
+
File.open(gemfile_path, "a") do |f|
|
|
62
|
+
f.puts 'gem "factory_bot"'
|
|
63
|
+
f.puts
|
|
64
|
+
f.puts 'group :development do'
|
|
65
|
+
f.puts ' gem "rubocop"'
|
|
66
|
+
f.puts ' gem "rubocop-rails"'
|
|
67
|
+
f.puts ' gem "rubocop-rspec"'
|
|
68
|
+
f.puts ' gem "bullet"'
|
|
69
|
+
f.puts 'end'
|
|
70
|
+
f.puts
|
|
71
|
+
f.puts 'group :development, :test do'
|
|
72
|
+
f.puts ' gem "rspec-rails"'
|
|
73
|
+
f.puts ' gem "test-prof"'
|
|
74
|
+
f.puts ' gem "simplecov"'
|
|
75
|
+
f.puts 'end'
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
puts "Running: bundle install"
|
|
79
|
+
system("bundle", "install", chdir: app_dir) || abort("bundle install failed")
|
|
80
|
+
|
|
81
|
+
puts "Running: rails generate rspec:install"
|
|
82
|
+
system("bundle", "exec", "rails", "generate", "rspec:install", chdir: app_dir) || abort("rails generate rspec:install failed")
|
|
83
|
+
|
|
84
|
+
spec_helper_path = File.join(app_dir, "spec", "spec_helper.rb")
|
|
85
|
+
if File.exist?(spec_helper_path)
|
|
86
|
+
original = File.read(spec_helper_path)
|
|
87
|
+
File.write(spec_helper_path, %(require "simplecov"\nSimpleCov.start "rails"\n\n) + original)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
puts "Running: bundle exec rails g bullet:install"
|
|
91
|
+
system("bundle", "exec", "rails", "g", "bullet:install", chdir: app_dir) || abort("rails g bullet:install failed")
|
data/lib/rails/kompot.rb
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Generate unit specs for the given source files.
|
|
2
|
+
|
|
3
|
+
## Steps
|
|
4
|
+
|
|
5
|
+
1. Read each source file specified in `$ARGUMENTS` to understand its public API, dependencies, and DB interactions.
|
|
6
|
+
|
|
7
|
+
2. Look at existing specs in the project to learn conventions (describe/context/it structure, factory patterns, test-prof usage).
|
|
8
|
+
|
|
9
|
+
3. Write spec files following these rules:
|
|
10
|
+
- **Unit tests** — test each method/behavior in isolation; mock external dependencies
|
|
11
|
+
- Use `let_it_be` / `let_it_be_refined` instead of `let` / `let!` for DB-backed test data
|
|
12
|
+
- Use `AnyFixture` for shared reference data (roles, statuses, config records) that doesn't change across examples
|
|
13
|
+
- Spec file placement mirrors source: `app/models/user.rb` → `spec/models/user_spec.rb`
|
|
14
|
+
|
|
15
|
+
4. Run each new spec with `FPROF=1` to check DB record creation:
|
|
16
|
+
```bash
|
|
17
|
+
FPROF=1 bundle exec rspec <spec_file>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
5. Review the FPROF output. If unnecessary DB records are created per-example, refactor test data to use `let_it_be` or `AnyFixture`.
|
|
21
|
+
|
|
22
|
+
6. Fix any failures and re-run until all specs are green.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Analyze existing SimpleCov coverage results and write missing specs to improve coverage.
|
|
2
|
+
|
|
3
|
+
## Steps
|
|
4
|
+
|
|
5
|
+
1. Read the existing coverage report at `coverage/index.html`. Do not run the test suite — assume the user has already run it and the report is current.
|
|
6
|
+
|
|
7
|
+
2. Parse the HTML report for:
|
|
8
|
+
- **Overall coverage percentage**
|
|
9
|
+
- **Files below 80% coverage** — list each file with its coverage percentage
|
|
10
|
+
- **Uncovered lines** — for each low-coverage file, identify which methods or branches are not covered
|
|
11
|
+
|
|
12
|
+
3. For each low-coverage file, read the source file to understand what needs to be tested.
|
|
13
|
+
|
|
14
|
+
4. Write the missing specs:
|
|
15
|
+
- Create or extend the appropriate spec file (e.g. `spec/models/user_spec.rb`)
|
|
16
|
+
- Cover the uncovered methods, branches, and edge cases identified in step 2
|
|
17
|
+
- Follow existing spec conventions in the project (describe/context/it blocks, factory usage, etc.)
|
|
18
|
+
- **Unit tests** — test each method/behavior in isolation; mock external dependencies
|
|
19
|
+
- Use `let_it_be` / `let_it_be_refined` instead of `let` / `let!` for DB-backed test data
|
|
20
|
+
- Use `AnyFixture` for shared reference data (roles, statuses, config records) that doesn't change across examples
|
|
21
|
+
|
|
22
|
+
5. Run each new or modified spec with `FPROF=1` to check DB record creation:
|
|
23
|
+
```bash
|
|
24
|
+
FPROF=1 bundle exec rspec <spec_file>
|
|
25
|
+
```
|
|
26
|
+
Review the FPROF output — if unnecessary DB records are created per-example, refactor test data to use `let_it_be` or `AnyFixture`. Fix any failures before moving on to the next file.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
Analyze the staged and unstaged changes and create a commit with a minimal, accurate message.
|
|
2
|
+
|
|
3
|
+
## Steps
|
|
4
|
+
|
|
5
|
+
1. Inspect what has changed:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git status
|
|
9
|
+
git diff
|
|
10
|
+
git diff --cached
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
2. Analyze the changes and derive the commit message:
|
|
14
|
+
- Identify the single most important thing the changes accomplish.
|
|
15
|
+
- Use the conventional format: `<type>: <short description>` (e.g. `feat:`, `fix:`, `refactor:`, `test:`, `chore:`).
|
|
16
|
+
- Keep the subject line under 72 characters.
|
|
17
|
+
- Use the imperative mood ("add", "fix", "remove" — not "added", "fixes").
|
|
18
|
+
- Do not pad with filler words or repeat the diff verbatim.
|
|
19
|
+
- If the changes span genuinely unrelated concerns, split into multiple commits.
|
|
20
|
+
|
|
21
|
+
3. Stage all relevant changes and commit:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
git add -p # or git add <specific files>
|
|
25
|
+
git commit -m "<type>: <short description>"
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Do not include `--no-verify` or any flag that bypasses hooks.
|
|
29
|
+
Do not include co-authors in a commit.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Run all quality gates in sequence, fixing issues as you go, until everything is green.
|
|
2
|
+
|
|
3
|
+
## Steps
|
|
4
|
+
|
|
5
|
+
1. **Tests + FPROF** — Run `FPROF=1 bundle exec rspec`. If any specs fail, use `/fix` to diagnose and resolve each failure. Review FPROF output — if any example group creates excessive DB records, refactor to use `let_it_be` / `before_all`. Re-run until green.
|
|
6
|
+
|
|
7
|
+
2. **Code coverage** — Run `bundle exec rspec` to generate a fresh SimpleCov report, then run the `/code-coverage` skill to identify under-covered files and write missing specs. Re-run until all files meet the 80% threshold.
|
|
8
|
+
|
|
9
|
+
3. **Lint** — Run the `/lint` skill to auto-correct and fix all RuboCop offenses.
|
|
10
|
+
|
|
11
|
+
4. **Code review** — Run the `/review-pr` skill to diff against main, review for quality issues, and fix all blockers.
|
|
12
|
+
|
|
13
|
+
5. **Documentation** — Identify changed `.rb` files under `app/` with:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
git diff --name-only main | grep '^app/.*\.rb$'
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Run the `/docs` skill on those files to create or update their documentation in `docs/`.
|
|
20
|
+
|
|
21
|
+
6. **Final verification** — Re-run `FPROF=1 bundle exec rspec` and `bundle exec rubocop`. If anything fails, return to the relevant step. Repeat until both are clean.
|
|
22
|
+
|
|
23
|
+
7. **Commit** — If there are uncommitted changes, run the `/commit` skill.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
Generate or update markdown documentation for one or more `app/` source files.
|
|
2
|
+
|
|
3
|
+
## Usage
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
/docs app/models/user.rb app/services/payment_processor.rb
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
`$ARGUMENTS` — one or more file paths under `app/` (space-separated).
|
|
10
|
+
|
|
11
|
+
## Steps
|
|
12
|
+
|
|
13
|
+
For each file path in `$ARGUMENTS`:
|
|
14
|
+
|
|
15
|
+
1. **Determine the mirror path** — replace the leading `app/` with `docs/` and the `.rb` extension with `.md`.
|
|
16
|
+
- Example: `app/models/user.rb` → `docs/models/user.md`
|
|
17
|
+
|
|
18
|
+
2. **Read the source file** to understand the class/module: its purpose, public interface, constants, callbacks, validations, associations, and any inline comments.
|
|
19
|
+
|
|
20
|
+
3. **Infer input/output types** for each method using:
|
|
21
|
+
- Method signatures and parameter names
|
|
22
|
+
- Type annotations or Sorbet/RBS signatures if present
|
|
23
|
+
- Default values (e.g. `limit: 10` implies Integer)
|
|
24
|
+
- Guard clauses and conditional branches (e.g. `return if user.nil?` implies nullable)
|
|
25
|
+
- Return expressions and their literal types
|
|
26
|
+
- Database schema for model attributes — read `db/schema.rb` to find column types
|
|
27
|
+
- Usage patterns — grep the codebase for calls to the method and observe argument types passed
|
|
28
|
+
|
|
29
|
+
4. **Identify business flows** — grep the codebase for references to the class/module name to find its callers and the contexts in which it is used.
|
|
30
|
+
|
|
31
|
+
5. **Check whether the docs file already exists**:
|
|
32
|
+
- If it **exists**: read it, then update it — preserve any manually-added notes or sections not generated by this skill, but refresh auto-generated sections (Purpose, Business flows, Methods) from the current source.
|
|
33
|
+
- If it **does not exist**: create the parent directories if needed and write the file from scratch.
|
|
34
|
+
|
|
35
|
+
6. **Write the docs file** using the structure below.
|
|
36
|
+
|
|
37
|
+
7. **Verify** that the docs file exists and is non-empty after writing.
|
|
38
|
+
|
|
39
|
+
## Doc file structure
|
|
40
|
+
|
|
41
|
+
```markdown
|
|
42
|
+
# ClassName
|
|
43
|
+
|
|
44
|
+
## Purpose
|
|
45
|
+
One-paragraph description of what this class/module does and why it exists.
|
|
46
|
+
|
|
47
|
+
## Business flows
|
|
48
|
+
- Flow or use case 1 — brief description of how this class is involved
|
|
49
|
+
- Flow or use case 2 — ...
|
|
50
|
+
(List only flows discovered from grepping callers; omit if no callers found.)
|
|
51
|
+
|
|
52
|
+
## Methods
|
|
53
|
+
|
|
54
|
+
### `.class_method(arg1, arg2)`
|
|
55
|
+
- **Input**: `arg1` — Type, description; `arg2` — Type, description
|
|
56
|
+
- **Output**: Type — description
|
|
57
|
+
- What the method does.
|
|
58
|
+
|
|
59
|
+
### `#instance_method(arg1)`
|
|
60
|
+
- **Input**: `arg1` — Type, description
|
|
61
|
+
- **Output**: Type — description
|
|
62
|
+
- What the method does.
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Conventions:**
|
|
66
|
+
- Prefix class methods with `.` and instance methods with `#`.
|
|
67
|
+
- Document only public methods. Skip private/protected methods unless they are the primary interface.
|
|
68
|
+
- For model attributes (columns), list them in a `## Attributes` section with column type and description instead of under Methods.
|
|
69
|
+
- If the class has no public methods beyond ActiveRecord defaults, omit the Methods section.
|
|
70
|
+
|
|
71
|
+
## Example
|
|
72
|
+
|
|
73
|
+
Below is a filled-in example for `app/services/payment_processor.rb` → `docs/services/payment_processor.md`:
|
|
74
|
+
|
|
75
|
+
```markdown
|
|
76
|
+
# PaymentProcessor
|
|
77
|
+
|
|
78
|
+
## Purpose
|
|
79
|
+
Handles charge creation and refund processing against the Stripe API. Wraps the raw Stripe client so
|
|
80
|
+
controllers and background jobs never interact with the gateway directly. All monetary amounts are
|
|
81
|
+
expected in cents (Integer) and all currency codes follow ISO 4217 (e.g. `"usd"`).
|
|
82
|
+
|
|
83
|
+
## Business flows
|
|
84
|
+
- **Checkout** (`app/controllers/api/v1/orders_controller.rb`) — calls `.charge` after an order is
|
|
85
|
+
confirmed to capture payment before fulfillment begins.
|
|
86
|
+
- **Subscription renewal** (`app/jobs/renewal_job.rb`) — calls `.charge` on a recurring schedule;
|
|
87
|
+
on failure, calls `#refund` for any partial capture before retrying.
|
|
88
|
+
- **Support refunds** (`app/services/support_action_service.rb`) — calls `#refund` when a support
|
|
89
|
+
agent issues a full or partial refund from the admin panel.
|
|
90
|
+
|
|
91
|
+
## Attributes
|
|
92
|
+
> `PaymentProcessor` is a plain service object, not an ActiveRecord model — it has no database
|
|
93
|
+
> columns. See `app/models/payment.rb` for the persisted payment record.
|
|
94
|
+
|
|
95
|
+
## Methods
|
|
96
|
+
|
|
97
|
+
### `.charge(user:, amount_cents:, currency: "usd")`
|
|
98
|
+
- **Input**: `user:` — User, the account being charged (used to look up the stored Stripe customer
|
|
99
|
+
ID); `amount_cents:` — Integer, amount in cents (must be > 0); `currency:` — String, ISO 4217
|
|
100
|
+
currency code (default `"usd"`)
|
|
101
|
+
- **Output**: `Payment` — a persisted `Payment` record with `status: "succeeded"` on success, or
|
|
102
|
+
raises `PaymentProcessor::ChargeError` on gateway failure
|
|
103
|
+
- Creates a Stripe `PaymentIntent`, confirms it immediately, then persists a `Payment` record linked
|
|
104
|
+
to the user. Raises `ChargeError` (wrapping the Stripe exception) if the charge is declined or
|
|
105
|
+
the gateway is unreachable.
|
|
106
|
+
|
|
107
|
+
### `.supported_currencies`
|
|
108
|
+
- **Input**: none
|
|
109
|
+
- **Output**: Array\<String\> — list of ISO 4217 currency codes accepted by the current Stripe
|
|
110
|
+
account (e.g. `["usd", "eur", "gbp"]`)
|
|
111
|
+
- Fetches the list from Stripe on first call and memoizes it for the lifetime of the process.
|
|
112
|
+
|
|
113
|
+
### `#refund(payment:, amount_cents: nil)`
|
|
114
|
+
- **Input**: `payment:` — Payment, the record to refund (must have `status: "succeeded"`);
|
|
115
|
+
`amount_cents:` — Integer | nil, partial refund amount in cents; if `nil`, refunds the full
|
|
116
|
+
original charge
|
|
117
|
+
- **Output**: `Payment` — the same record, updated with `status: "refunded"` (full) or
|
|
118
|
+
`status: "partially_refunded"`
|
|
119
|
+
- Issues a Stripe refund for the given `PaymentIntent`. Updates the `Payment` record in a
|
|
120
|
+
transaction so the record and Stripe stay in sync. Raises `PaymentProcessor::RefundError` if the
|
|
121
|
+
payment is already fully refunded or if the gateway call fails.
|
|
122
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Diagnose and fix a failing test, RuboCop offense, or error. Pass a description of the problem as the argument.
|
|
2
|
+
|
|
3
|
+
Usage: `/fix <description of the problem>`
|
|
4
|
+
|
|
5
|
+
Examples:
|
|
6
|
+
- `/fix bundle exec rspec spec/models/user_spec.rb:42 is failing`
|
|
7
|
+
- `/fix rubocop offense: Metrics/MethodLength in app/services/user_service.rb`
|
|
8
|
+
- `/fix NoMethodError: undefined method 'foo' for nil:NilClass in app/controllers/users_controller.rb`
|
|
9
|
+
|
|
10
|
+
## Steps
|
|
11
|
+
|
|
12
|
+
1. Read the relevant file(s) identified in the problem description.
|
|
13
|
+
|
|
14
|
+
2. Diagnose the root cause — do not guess; trace the actual error or failing assertion.
|
|
15
|
+
|
|
16
|
+
3. Apply the minimal fix needed to resolve the issue.
|
|
17
|
+
|
|
18
|
+
4. Verify the fix by re-running the relevant command:
|
|
19
|
+
- **Failing test**: `bundle exec rspec <path/to/spec_file>` (use the specific file and line if available)
|
|
20
|
+
- **RuboCop offense**: `bundle exec rubocop <path/to/file>`
|
|
21
|
+
- **Runtime error**: re-run the command or request that raised the error
|
|
22
|
+
|
|
23
|
+
5. If the fix passes verification, report what was changed and why. If it still fails, diagnose further before trying another approach.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Run RuboCop on changed files or the whole project, auto-correct fixable offenses, then fix any remaining offenses by editing the code directly.
|
|
2
|
+
|
|
3
|
+
## Steps
|
|
4
|
+
|
|
5
|
+
1. Get the list of changed Ruby files:
|
|
6
|
+
```bash
|
|
7
|
+
git diff --name-only HEAD | grep '\.rb$'
|
|
8
|
+
```
|
|
9
|
+
If there are changed files, run RuboCop on those files. If there are no changed files (e.g. clean working tree), run RuboCop on the whole project.
|
|
10
|
+
|
|
11
|
+
2. Run RuboCop:
|
|
12
|
+
- On changed files: `bundle exec rubocop <file1> <file2> ...`
|
|
13
|
+
- On whole project: `bundle exec rubocop`
|
|
14
|
+
|
|
15
|
+
3. If any offenses are found, attempt auto-correction:
|
|
16
|
+
```bash
|
|
17
|
+
bundle exec rubocop -A <files or blank for all>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
4. Re-run RuboCop to see what remains after auto-correction.
|
|
21
|
+
|
|
22
|
+
5. For each remaining offense that RuboCop could not auto-correct:
|
|
23
|
+
- Read the offending file
|
|
24
|
+
- Understand the root cause of the offense (don't just silence the cop)
|
|
25
|
+
- Edit the code to fix it properly
|
|
26
|
+
- Repeat for all remaining offenses
|
|
27
|
+
|
|
28
|
+
6. Re-run RuboCop to confirm all offenses are resolved and no new ones were introduced.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
Review the current branch against main and provide actionable feedback.
|
|
2
|
+
|
|
3
|
+
## Steps
|
|
4
|
+
|
|
5
|
+
1. Get the diff of the current branch against main:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git diff main...HEAD
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
2. Also get the list of changed files:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
git diff --name-only main...HEAD
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
3. Review the changes for:
|
|
18
|
+
- **Code quality** — clarity, duplication, naming, Rails conventions
|
|
19
|
+
- **N+1 queries** — look for loops with ActiveRecord calls that lack `.includes`/`.preload`/`.eager_load`; Bullet will surface these at runtime but flag obvious ones in review
|
|
20
|
+
- **Missing specs** — for each new model, controller, service, or public method, check that a corresponding spec exists or is added in this PR
|
|
21
|
+
- **RuboCop compliance** — flag style issues not caught by auto-correct (complex logic, missing frozen_string_literal, etc.)
|
|
22
|
+
- **Documentation type consistency** — For each changed file under `app/`, check whether a corresponding `docs/` file exists (mirror path: replace `app/` prefix with `docs/` and `.rb` with `.md`). If it does, read the documented input/output types for each method. Then inspect callers of those methods in the diff and verify that arguments passed are consistent with the documented types. Flag type mismatches as **blockers**.
|
|
23
|
+
|
|
24
|
+
4. End with a summary: overall assessment, blockers vs. suggestions, and any positive highlights.
|
|
25
|
+
|
|
26
|
+
5. Fix every **blocker** identified in the summary:
|
|
27
|
+
- Edit the relevant source files directly to resolve each blocking issue.
|
|
28
|
+
- After applying fixes, re-run the test suite and RuboCop to verify no regressions were introduced:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
bundle exec rspec
|
|
32
|
+
bundle exec rubocop
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
- If new failures appear, fix them before finishing.
|
data/templates/CLAUDE.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Project
|
|
2
|
+
|
|
3
|
+
This is a Rails API-only application generated with [rails-kompot](https://github.com/kompoteria/rails-kompot).
|
|
4
|
+
|
|
5
|
+
## Stack
|
|
6
|
+
|
|
7
|
+
- **Rails** — API-only mode (`config.api_only = true`)
|
|
8
|
+
- **PostgreSQL** — primary database
|
|
9
|
+
- **Minimal** — only essential gems included (`--minimal` flag)
|
|
10
|
+
- **RSpec** — test framework (rspec-rails), with SimpleCov for coverage and test-prof for profiling
|
|
11
|
+
- **RuboCop** — linting and style enforcement (rubocop-rails, rubocop-rspec)
|
|
12
|
+
- **Bullet** — N+1 query detection (enabled in development)
|
|
13
|
+
|
|
14
|
+
## Key conventions
|
|
15
|
+
|
|
16
|
+
- Routes live in `config/routes.rb`; prefer namespaced API versioning (e.g. `namespace :api { namespace :v1 { ... } }`)
|
|
17
|
+
- Controllers inherit from `ActionController::API`
|
|
18
|
+
- Use `render json:` for responses; avoid views and assets
|
|
19
|
+
- Keep business logic out of controllers — use plain Ruby objects or service objects in `app/`
|
|
20
|
+
- Database credentials are in `config/database.yml`; use environment variables for secrets
|
|
21
|
+
|
|
22
|
+
## Setup
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
bin/rails db:create db:migrate
|
|
26
|
+
bin/rails server
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Testing
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Run the full test suite
|
|
33
|
+
bundle exec rspec
|
|
34
|
+
|
|
35
|
+
# Run a specific file
|
|
36
|
+
bundle exec rspec spec/models/user_spec.rb
|
|
37
|
+
|
|
38
|
+
# Run a specific example
|
|
39
|
+
bundle exec rspec spec/models/user_spec.rb:42
|
|
40
|
+
|
|
41
|
+
# Run with coverage report (SimpleCov outputs to coverage/)
|
|
42
|
+
bundle exec rspec
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Linting
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Check for offenses
|
|
49
|
+
bundle exec rubocop
|
|
50
|
+
|
|
51
|
+
# Auto-correct fixable offenses
|
|
52
|
+
bundle exec rubocop -A
|
|
53
|
+
|
|
54
|
+
# Check a specific file
|
|
55
|
+
bundle exec rubocop app/models/user.rb
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Available Claude skills
|
|
59
|
+
|
|
60
|
+
This project includes custom Claude Code slash commands in `.claude/commands/`:
|
|
61
|
+
|
|
62
|
+
- `/lint` — Run RuboCop on changed files (or whole project) and auto-correct fixable offenses
|
|
63
|
+
- `/review-pr` — Diff current branch against main and review for code quality, N+1s, missing specs, and style
|
|
64
|
+
- `/fix` — Diagnose and fix a failing test, RuboCop offense, or error message
|
|
65
|
+
- `/code-coverage` — Run RSpec, analyze SimpleCov results, and suggest specs to add
|
|
66
|
+
- `/add-tests` — Generate unit specs for given source files using test-prof conventions
|
|
67
|
+
- `/commit` — Analyze staged and unstaged changes and create a commit with a minimal, accurate conventional message
|
|
68
|
+
- `/docs` — Generate or update markdown documentation in `docs/` for given `app/` source files, mirroring their path structure
|
|
69
|
+
- `/deliver` — Run all quality gates (tests+FPROF, coverage, RuboCop, code review) in a loop, fixing issues until everything is green, then commit
|
|
70
|
+
|
|
71
|
+
## Self-improvement
|
|
72
|
+
|
|
73
|
+
When a skill fails, produces incorrect output, or the user requests adjustments to Claude's behavior (e.g. "always do X", "stop doing Y", "add Z to reviews"), ask the user whether they'd like to update the relevant skill file in `.claude/commands/` or `CLAUDE.md` to capture the adjustment. This prevents repeating the same mistakes across sessions.
|
metadata
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rails-kompot
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Anatolii Kryvishyn
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: railties
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.0'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '9'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: '7.0'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '9'
|
|
32
|
+
description: A CLI wrapper around `rails new` that applies preset flags (-d postgresql
|
|
33
|
+
-T --api --minimal).
|
|
34
|
+
email:
|
|
35
|
+
- 9845250+anatoliikryvishyn@users.noreply.github.com
|
|
36
|
+
executables:
|
|
37
|
+
- rails-kompot
|
|
38
|
+
extensions: []
|
|
39
|
+
extra_rdoc_files: []
|
|
40
|
+
files:
|
|
41
|
+
- CHANGELOG.md
|
|
42
|
+
- LICENSE.txt
|
|
43
|
+
- README.md
|
|
44
|
+
- Rakefile
|
|
45
|
+
- exe/rails-kompot
|
|
46
|
+
- lib/rails/kompot.rb
|
|
47
|
+
- lib/rails/kompot/version.rb
|
|
48
|
+
- sig/rails/kompot.rbs
|
|
49
|
+
- templates/.claude/commands/add-tests.md
|
|
50
|
+
- templates/.claude/commands/code-coverage.md
|
|
51
|
+
- templates/.claude/commands/commit.md
|
|
52
|
+
- templates/.claude/commands/deliver.md
|
|
53
|
+
- templates/.claude/commands/docs.md
|
|
54
|
+
- templates/.claude/commands/fix.md
|
|
55
|
+
- templates/.claude/commands/lint.md
|
|
56
|
+
- templates/.claude/commands/review-pr.md
|
|
57
|
+
- templates/.rubocop.yml
|
|
58
|
+
- templates/CLAUDE.md
|
|
59
|
+
homepage: https://github.com/kompoteria/rails-kompot
|
|
60
|
+
licenses:
|
|
61
|
+
- MIT
|
|
62
|
+
metadata:
|
|
63
|
+
homepage_uri: https://github.com/kompoteria/rails-kompot
|
|
64
|
+
source_code_uri: https://github.com/kompoteria/rails-kompot
|
|
65
|
+
changelog_uri: https://github.com/kompoteria/rails-kompot/blob/main/CHANGELOG.md
|
|
66
|
+
bug_tracker_uri: https://github.com/kompoteria/rails-kompot/issues
|
|
67
|
+
rubygems_mfa_required: 'true'
|
|
68
|
+
rdoc_options: []
|
|
69
|
+
require_paths:
|
|
70
|
+
- lib
|
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: 3.0.0
|
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
77
|
+
requirements:
|
|
78
|
+
- - ">="
|
|
79
|
+
- !ruby/object:Gem::Version
|
|
80
|
+
version: '0'
|
|
81
|
+
requirements: []
|
|
82
|
+
rubygems_version: 4.0.3
|
|
83
|
+
specification_version: 4
|
|
84
|
+
summary: 'Rails new with sensible defaults: PostgreSQL, API-only, minimal, no test
|
|
85
|
+
framework.'
|
|
86
|
+
test_files: []
|