rails_claude_skills 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/.github/ISSUE_TEMPLATE/bug_report.yml +134 -0
- data/.github/ISSUE_TEMPLATE/config.yml +11 -0
- data/.github/ISSUE_TEMPLATE/feature_request.yml +129 -0
- data/.github/ISSUE_TEMPLATE/question.yml +90 -0
- data/.github/dependabot.yml +19 -0
- data/.github/workflows/ci.yml +77 -0
- data/.github/workflows/release.yml +66 -0
- data/.rubocop.yml +52 -0
- data/CHANGELOG.md +94 -0
- data/CLAUDE.md +332 -0
- data/CODE_OF_CONDUCT.md +134 -0
- data/CONTRIBUTING.md +580 -0
- data/LICENSE.txt +21 -0
- data/README.md +544 -0
- data/Rakefile +8 -0
- data/lib/generators/claude/agent/agent_generator.rb +71 -0
- data/lib/generators/claude/agent/templates/agent.md.tt +62 -0
- data/lib/generators/claude/command/command_generator.rb +50 -0
- data/lib/generators/claude/command/templates/command.md.tt +28 -0
- data/lib/generators/claude/commands_library/create-pr.md +27 -0
- data/lib/generators/claude/commands_library/dbchange.md +19 -0
- data/lib/generators/claude/commands_library/quality.md +20 -0
- data/lib/generators/claude/commands_library/stimulus.md +19 -0
- data/lib/generators/claude/commands_library/turbo-feature.md +17 -0
- data/lib/generators/claude/install/install_generator.rb +211 -0
- data/lib/generators/claude/install/templates/README.md.tt +59 -0
- data/lib/generators/claude/install/templates/USAGE +28 -0
- data/lib/generators/claude/install/templates/agents/api-dev.md.tt +46 -0
- data/lib/generators/claude/install/templates/agents/fullstack-dev.md.tt +48 -0
- data/lib/generators/claude/install/templates/agents/rails-developer.md.tt +40 -0
- data/lib/generators/claude/install/templates/settings.local.json.tt +13 -0
- data/lib/generators/claude/rule/rule_generator.rb +175 -0
- data/lib/generators/claude/rule/templates/rule.md.tt +7 -0
- data/lib/generators/claude/rules_library/code-style.md +37 -0
- data/lib/generators/claude/rules_library/database.md +47 -0
- data/lib/generators/claude/rules_library/hotwire.md +56 -0
- data/lib/generators/claude/rules_library/security.md +54 -0
- data/lib/generators/claude/rules_library/testing.md +47 -0
- data/lib/generators/claude/skill/skill_generator.rb +196 -0
- data/lib/generators/claude/skill/templates/SKILL.md.tt +27 -0
- data/lib/generators/claude/skills_library/create-task-files/SKILL.md +311 -0
- data/lib/generators/claude/skills_library/create-task-files/templates/bug.md +60 -0
- data/lib/generators/claude/skills_library/create-task-files/templates/epic.md +47 -0
- data/lib/generators/claude/skills_library/create-task-files/templates/issue.md +45 -0
- data/lib/generators/claude/skills_library/create-task-files/templates/user-story.md +57 -0
- data/lib/generators/claude/skills_library/minitest-testing/SKILL.md +398 -0
- data/lib/generators/claude/skills_library/minitest-testing/references/examples.md +889 -0
- data/lib/generators/claude/skills_library/plan-feature/SKILL.md +253 -0
- data/lib/generators/claude/skills_library/rails-api-controllers/SKILL.md +1041 -0
- data/lib/generators/claude/skills_library/rails-api-controllers/references/api-documentation.md +422 -0
- data/lib/generators/claude/skills_library/rails-api-controllers/references/serialization.md +456 -0
- data/lib/generators/claude/skills_library/rails-auth-with-devise/SKILL.md +191 -0
- data/lib/generators/claude/skills_library/rails-auth-with-devise/references/advanced.md +331 -0
- data/lib/generators/claude/skills_library/rails-auth-with-devise/references/api-auth.md +266 -0
- data/lib/generators/claude/skills_library/rails-auth-with-devise/references/omniauth.md +194 -0
- data/lib/generators/claude/skills_library/rails-authorization-cancancan/SKILL.md +603 -0
- data/lib/generators/claude/skills_library/rails-authorization-cancancan/references/api-authorization.md +543 -0
- data/lib/generators/claude/skills_library/rails-authorization-cancancan/references/complex-permissions.md +572 -0
- data/lib/generators/claude/skills_library/rails-authorization-cancancan/references/multi-tenancy.md +373 -0
- data/lib/generators/claude/skills_library/rails-controllers/SKILL.md +514 -0
- data/lib/generators/claude/skills_library/rails-debugging/SKILL.md +260 -0
- data/lib/generators/claude/skills_library/rails-deployment/SKILL.md +437 -0
- data/lib/generators/claude/skills_library/rails-deployment/references/examples.md +901 -0
- data/lib/generators/claude/skills_library/rails-hotwire/SKILL.md +367 -0
- data/lib/generators/claude/skills_library/rails-jobs/MISSION_CONTROL_SETUP.md +639 -0
- data/lib/generators/claude/skills_library/rails-jobs/SKILL.md +704 -0
- data/lib/generators/claude/skills_library/rails-mailers/SKILL.md +549 -0
- data/lib/generators/claude/skills_library/rails-models/SKILL.md +379 -0
- data/lib/generators/claude/skills_library/rails-pagination-kaminari/SKILL.md +622 -0
- data/lib/generators/claude/skills_library/rails-pagination-kaminari/references/api-pagination.md +523 -0
- data/lib/generators/claude/skills_library/rails-pagination-kaminari/references/custom-themes.md +498 -0
- data/lib/generators/claude/skills_library/rails-pagination-kaminari/references/performance.md +478 -0
- data/lib/generators/claude/skills_library/rails-views/SKILL.md +508 -0
- data/lib/generators/claude/skills_library/refine-requirements/SKILL.md +226 -0
- data/lib/generators/claude/skills_library/refine-requirements/references/examples.md +344 -0
- data/lib/generators/claude/skills_library/refine-requirements/references/reference.md +298 -0
- data/lib/generators/claude/skills_library/rspec-testing/SKILL.md +572 -0
- data/lib/generators/claude/skills_library/rspec-testing/references/better_specs_guide.md +273 -0
- data/lib/generators/claude/skills_library/rspec-testing/references/thoughtbot_patterns.md +407 -0
- data/lib/generators/claude/skills_library/tailwindcss/SKILL.md +371 -0
- data/lib/generators/claude/views/views_generator.rb +113 -0
- data/lib/rails_claude_skills/railtie.rb +16 -0
- data/lib/rails_claude_skills/version.rb +5 -0
- data/lib/rails_claude_skills.rb +27 -0
- data/sig/rails_claude_skills.rbs +4 -0
- metadata +199 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# OmniAuth Integration with Devise
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
- [Basic Setup](#basic-setup)
|
|
5
|
+
- [Provider Configuration](#provider-configuration)
|
|
6
|
+
- [User Model Setup](#user-model-setup)
|
|
7
|
+
- [Callbacks Controller](#callbacks-controller)
|
|
8
|
+
- [Common Providers](#common-providers)
|
|
9
|
+
- [Testing OmniAuth](#testing-omniauth)
|
|
10
|
+
|
|
11
|
+
## Basic Setup
|
|
12
|
+
|
|
13
|
+
1. Add gems to Gemfile:
|
|
14
|
+
```ruby
|
|
15
|
+
gem 'omniauth'
|
|
16
|
+
gem 'omniauth-rails_csrf_protection' # Required for OmniAuth 2.0+
|
|
17
|
+
gem 'omniauth-google-oauth2' # or other providers
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
2. Configure in `config/initializers/devise.rb`:
|
|
21
|
+
```ruby
|
|
22
|
+
config.omniauth :google_oauth2,
|
|
23
|
+
ENV['GOOGLE_CLIENT_ID'],
|
|
24
|
+
ENV['GOOGLE_CLIENT_SECRET'],
|
|
25
|
+
scope: 'email,profile'
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Provider Configuration
|
|
29
|
+
|
|
30
|
+
### Google OAuth2
|
|
31
|
+
```ruby
|
|
32
|
+
config.omniauth :google_oauth2,
|
|
33
|
+
ENV['GOOGLE_CLIENT_ID'],
|
|
34
|
+
ENV['GOOGLE_CLIENT_SECRET'],
|
|
35
|
+
{
|
|
36
|
+
scope: 'email,profile',
|
|
37
|
+
prompt: 'select_account',
|
|
38
|
+
image_aspect_ratio: 'square',
|
|
39
|
+
image_size: 50
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Facebook
|
|
44
|
+
```ruby
|
|
45
|
+
gem 'omniauth-facebook'
|
|
46
|
+
|
|
47
|
+
config.omniauth :facebook,
|
|
48
|
+
ENV['FACEBOOK_APP_ID'],
|
|
49
|
+
ENV['FACEBOOK_APP_SECRET'],
|
|
50
|
+
scope: 'email,public_profile',
|
|
51
|
+
info_fields: 'email,name,first_name,last_name'
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### GitHub
|
|
55
|
+
```ruby
|
|
56
|
+
gem 'omniauth-github'
|
|
57
|
+
|
|
58
|
+
config.omniauth :github,
|
|
59
|
+
ENV['GITHUB_CLIENT_ID'],
|
|
60
|
+
ENV['GITHUB_CLIENT_SECRET'],
|
|
61
|
+
scope: 'user:email'
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## User Model Setup
|
|
65
|
+
|
|
66
|
+
Add `:omniauthable` to User model and create migration:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
rails g migration AddOmniauthToUsers provider:string uid:string
|
|
70
|
+
rails db:migrate
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```ruby
|
|
74
|
+
# app/models/user.rb
|
|
75
|
+
class User < ApplicationRecord
|
|
76
|
+
devise :database_authenticatable, :registerable,
|
|
77
|
+
:recoverable, :rememberable, :validatable,
|
|
78
|
+
:omniauthable, omniauth_providers: [:google_oauth2, :facebook, :github]
|
|
79
|
+
|
|
80
|
+
def self.from_omniauth(auth)
|
|
81
|
+
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
|
|
82
|
+
user.email = auth.info.email
|
|
83
|
+
user.password = Devise.friendly_token[0, 20]
|
|
84
|
+
user.name = auth.info.name # if you have a name column
|
|
85
|
+
# user.avatar = auth.info.image # if you have avatar column
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Callbacks Controller
|
|
92
|
+
|
|
93
|
+
Create `app/controllers/users/omniauth_callbacks_controller.rb`:
|
|
94
|
+
|
|
95
|
+
```ruby
|
|
96
|
+
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
|
97
|
+
def google_oauth2
|
|
98
|
+
handle_auth("Google")
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def facebook
|
|
102
|
+
handle_auth("Facebook")
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def github
|
|
106
|
+
handle_auth("GitHub")
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def failure
|
|
110
|
+
redirect_to root_path, alert: "Authentication failed: #{failure_message}"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
private
|
|
114
|
+
|
|
115
|
+
def handle_auth(provider)
|
|
116
|
+
@user = User.from_omniauth(request.env['omniauth.auth'])
|
|
117
|
+
|
|
118
|
+
if @user.persisted?
|
|
119
|
+
sign_in_and_redirect @user, event: :authentication
|
|
120
|
+
set_flash_message(:notice, :success, kind: provider) if is_navigational_format?
|
|
121
|
+
else
|
|
122
|
+
session['devise.auth_data'] = request.env['omniauth.auth'].except(:extra)
|
|
123
|
+
redirect_to new_user_registration_url, alert: @user.errors.full_messages.join("\n")
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Update routes:
|
|
130
|
+
```ruby
|
|
131
|
+
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## View Links
|
|
135
|
+
|
|
136
|
+
```erb
|
|
137
|
+
<%# Sign in links %>
|
|
138
|
+
<%= button_to "Sign in with Google", user_google_oauth2_omniauth_authorize_path, data: { turbo: false } %>
|
|
139
|
+
<%= button_to "Sign in with Facebook", user_facebook_omniauth_authorize_path, data: { turbo: false } %>
|
|
140
|
+
<%= button_to "Sign in with GitHub", user_github_omniauth_authorize_path, data: { turbo: false } %>
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Note: Use `button_to` (POST) instead of `link_to` (GET) for OmniAuth 2.0+ security.
|
|
144
|
+
|
|
145
|
+
## Handling Existing Users
|
|
146
|
+
|
|
147
|
+
To allow linking OAuth to existing accounts:
|
|
148
|
+
|
|
149
|
+
```ruby
|
|
150
|
+
def self.from_omniauth(auth)
|
|
151
|
+
user = where(email: auth.info.email).first
|
|
152
|
+
|
|
153
|
+
if user
|
|
154
|
+
user.update(provider: auth.provider, uid: auth.uid) unless user.provider
|
|
155
|
+
user
|
|
156
|
+
else
|
|
157
|
+
where(provider: auth.provider, uid: auth.uid).first_or_create do |new_user|
|
|
158
|
+
new_user.email = auth.info.email
|
|
159
|
+
new_user.password = Devise.friendly_token[0, 20]
|
|
160
|
+
new_user.name = auth.info.name
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Testing OmniAuth
|
|
167
|
+
|
|
168
|
+
In `spec/rails_helper.rb` or test setup:
|
|
169
|
+
|
|
170
|
+
```ruby
|
|
171
|
+
OmniAuth.config.test_mode = true
|
|
172
|
+
|
|
173
|
+
OmniAuth.config.mock_auth[:google_oauth2] = OmniAuth::AuthHash.new({
|
|
174
|
+
provider: 'google_oauth2',
|
|
175
|
+
uid: '123456789',
|
|
176
|
+
info: {
|
|
177
|
+
email: 'test@example.com',
|
|
178
|
+
name: 'Test User',
|
|
179
|
+
image: 'https://example.com/image.jpg'
|
|
180
|
+
},
|
|
181
|
+
credentials: {
|
|
182
|
+
token: 'mock_token',
|
|
183
|
+
refresh_token: 'mock_refresh_token',
|
|
184
|
+
expires_at: Time.now + 1.week
|
|
185
|
+
}
|
|
186
|
+
})
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Reset after tests:
|
|
190
|
+
```ruby
|
|
191
|
+
after(:each) do
|
|
192
|
+
OmniAuth.config.mock_auth[:google_oauth2] = nil
|
|
193
|
+
end
|
|
194
|
+
```
|