Skip to content

Commit 2549821

Browse files
authored
v2 (#161)
1 parent 1d47a6f commit 2549821

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+3710
-493
lines changed

.claude/settings.local.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"permissions": {
3+
"allow": [
4+
"Bash(bundle exec rspec:*)",
5+
"Bash(RAILS_ENV=test bundle exec rails:*)"
6+
],
7+
"deny": [],
8+
"ask": []
9+
}
10+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
name: Update API Documentation
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- 'spec/requests/api/**'
8+
9+
permissions:
10+
contents: write
11+
12+
env:
13+
RAILS_ENV: test
14+
CI: true
15+
16+
jobs:
17+
update-docs:
18+
name: Generate and Update API Docs
19+
runs-on: ubuntu-latest
20+
timeout-minutes: 15
21+
22+
services:
23+
postgres:
24+
image: postgres:16
25+
env:
26+
POSTGRES_USER: postgres
27+
POSTGRES_PASSWORD: postgres
28+
POSTGRES_DB: test
29+
ports:
30+
- 5432:5432
31+
options: >-
32+
--health-cmd pg_isready
33+
--health-interval 10s
34+
--health-timeout 5s
35+
--health-retries 5
36+
37+
redis:
38+
image: redis:7
39+
ports:
40+
- 6379:6379
41+
options: >-
42+
--health-cmd "redis-cli ping"
43+
--health-interval 10s
44+
--health-timeout 5s
45+
--health-retries 5
46+
47+
steps:
48+
- name: Checkout code
49+
uses: actions/checkout@v5
50+
with:
51+
fetch-depth: 0
52+
ssh-key: "${{ secrets.PUSH_KEY }}"
53+
54+
- name: Setup Ruby
55+
uses: ruby/setup-ruby@v1
56+
with:
57+
bundler-cache: true
58+
59+
- name: Setup Node
60+
uses: actions/setup-node@v6
61+
with:
62+
node-version-file: '.nvmrc'
63+
cache: 'npm'
64+
65+
- name: Install dependencies
66+
run: |
67+
gem install bundler
68+
bundle install
69+
npm install
70+
71+
- name: Setup Database
72+
env:
73+
DATABASE_URL: postgres://postgres:postgres@localhost:5432/test
74+
run: |
75+
bundle exec rails db:create
76+
bundle exec rails db:schema:load
77+
78+
- name: Run API specs with OpenAPI generation
79+
env:
80+
OPENAPI: 1
81+
DATABASE_URL: postgres://postgres:postgres@localhost:5432/test
82+
REDIS_URL: redis://localhost:6379/0
83+
run: bundle exec rspec spec/requests/api --format progress
84+
85+
- name: Merge API Docs
86+
if: hashFiles('doc/openapi*.yaml') != ''
87+
run: bundle exec ./bin/merge-api-docs.rb
88+
89+
- name: Commit and push API Docs
90+
run: |
91+
git config --local user.email "[email protected]"
92+
git config --local user.name "GitHub Action"
93+
git add "doc/openapi.yaml"
94+
git commit -m "Update API Documentation [skip ci]" || echo "No changes to commit"
95+
git push origin main || echo "No changes to push"

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,4 @@
4242
# Ignore key files for decrypting credentials and more.
4343
/config/credentials/*.key
4444

45+
coverage

CLAUDE.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
3030
- `bundle exec rubocop -a` - Run linter with auto-fix
3131
- `bundle exec brakeman` - Run security vulnerability scanner
3232

33+
### API Documentation
34+
- `OPENAPI=1 bundle exec rspec spec/requests/api` - Generate OpenAPI/Swagger documentation from request specs
35+
- Access docs at `/admin/api-docs` (requires admin login)
36+
- **Automatic generation**: GitHub Actions automatically updates docs when API specs change on `main` branch
37+
- **Configuration files**:
38+
- `config/initializers/rspec_openapi.rb` - OpenAPI generation config
39+
- `config/initializers/rswag_ui.rb` - Swagger UI config
40+
- `config/initializers/rswag_api.rb` - API serving config
41+
- **Generated file**: `doc/openapi.yaml`
42+
- **Workflow**: `.github/workflows/update-api-docs.yml`
43+
- See `docs/api_documentation.md` for complete setup and usage
44+
3345
## Architecture Overview
3446

3547
### Core Purpose
@@ -134,6 +146,7 @@ A Rails 8 API backend that syncs college course schedules to Google Calendar wit
134146
7. **Template validation**: Calendar preference templates are validated; invalid syntax is rejected
135147
8. **OAuth token encryption**: All sensitive tokens are encrypted with Lockbox
136148
9. **Multi-email support**: Design features to support users with multiple connected Google accounts
149+
10. **API documentation auto-updates**: When modifying API endpoints, update request specs - docs regenerate automatically on `main` branch
137150

138151
## Common Development Workflows
139152

@@ -163,8 +176,18 @@ A Rails 8 API backend that syncs college course schedules to Google Calendar wit
163176
4. Write RSpec tests in `spec/policies/` to verify permissions
164177
5. See `docs/authorization.md` for policy patterns
165178

179+
### Adding/Updating API Endpoints
180+
1. Create/update controller action in `app/controllers/api/`
181+
2. Add request spec in `spec/requests/api/` - this generates the API docs
182+
3. Test locally: `OPENAPI=1 bundle exec rspec spec/requests/api`
183+
4. Check generated docs at `/admin/api-docs` (requires admin login)
184+
5. Docs auto-update on `main` branch via GitHub Actions
185+
6. To exclude specs from docs, add `openapi: false` to the describe block
186+
7. See `docs/api_documentation.md` for more details
187+
166188
### Running Tests for Specific Features
167189
- Authorization policies: `bundle exec rspec spec/policies/`
190+
- API endpoints: `bundle exec rspec spec/requests/api/` (or with `OPENAPI=1` to generate docs)
168191
- Calendar preferences: `bundle exec rspec spec/models/calendar_preference_spec.rb`
169192
- Template rendering: `bundle exec rspec spec/services/calendar_template_renderer_spec.rb`
170193
- Preference resolution: `bundle exec rspec spec/services/preference_resolver_spec.rb`

Gemfile

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ group :development, :test do
9696
gem "rubocop-rspec", "~> 3.8"
9797
gem "rubocop-rspec_rails", "~> 2.32"
9898
gem "query_count"
99-
gem "bullet"
99+
gem 'prosopite'
100100
end
101101

102102
group :development do
@@ -116,6 +116,8 @@ group :test do
116116
# Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]
117117
gem "capybara"
118118
gem "selenium-webdriver"
119+
gem "rspec-openapi", "~> 0.20"
120+
gem 'simplecov', require: false
119121
end
120122

121123
gem "faraday", "~> 2.14"
@@ -134,5 +136,10 @@ gem "neighbor"
134136
gem "log_bench"
135137

136138
gem "kaminari", "~> 1.2"
139+
gem "rswag-api", "~> 2.17.0"
140+
gem "rswag-ui", "~> 2.17.0"
141+
142+
gem "pghero", "~> 3.7"
143+
gem "pg_query", ">= 2"
137144

138145
gem "connection_pool", "~> 2.4"

0 commit comments

Comments
 (0)