--- description: API endpoint consistency — checklist to run after every API endpoint commit (Minitest behavior, rswag docs-only, API key auth). globs: app/controllers/api/v1/**/*.rb, spec/requests/api/v1/**/*.rb, test/controllers/api/v1/**/*.rb alwaysApply: false --- # API endpoint consistency (post-commit checklist) When adding or modifying API v1 endpoints, ensure the following so behavior, docs, and auth stay consistent. ## 1. Minitest behavioral coverage - **Location**: `test/controllers/api/v1/{resource}_controller_test.rb` - **Scope**: All new or changed actions must have Minitest coverage here. Do not rely on rswag specs for behavioral assertions. - **Pattern**: - Use `ApiKey.create!` (read and read_write scopes) and `api_headers(api_key)` → `{ "X-Api-Key" => api_key.display_key }`. Do not use OAuth/Bearer in these tests. - Cover: index/show (and create/update/destroy for write endpoints), read-only key blocking writes (403), invalid params (422), invalid date (422), not found (404), missing auth (401). - Follow existing API v1 test style: see [valuations_controller_test.rb](mdc:test/controllers/api/v1/valuations_controller_test.rb) and [transactions_controller_test.rb](mdc:test/controllers/api/v1/transactions_controller_test.rb). ## 2. rswag is docs-only - **Location**: `spec/requests/api/v1/{resource}_spec.rb` - **Rule**: These specs exist only for OpenAPI generation. Do not add `expect(...)` or `assert_*` (or any behavioral assertions). Use `run_test!` without custom assertion blocks so the spec only documents request/response and regenerates `docs/api/openapi.yaml`. - **Regenerate**: After edits, run `RAILS_ENV=test bundle exec rake rswag:specs:swaggerize`. ## 3. Same API key auth in all rswag specs - **Rule**: Every request spec in `spec/requests/api/v1/` must use the same API key auth pattern so generated docs are consistent. - **Pattern** (match holdings_spec, trades_spec, transactions_spec, etc.): ```ruby let(:api_key) do key = ApiKey.generate_secure_key ApiKey.create!( user: user, name: 'API Docs Key', key: key, scopes: %w[read_write], source: 'web' ) end let(:'X-Api-Key') { api_key.plain_key } ``` - Do not use Doorkeeper/OAuth in these specs (no `Doorkeeper::Application`, `Doorkeeper::AccessToken`, or `Authorization: "Bearer ..."`). Use API key only. Note: [valuations_spec.rb](mdc:spec/requests/api/v1/valuations_spec.rb) currently uses OAuth; update it to the API key pattern above when editing that file.