docit 0.4.0 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 39589c6800b65d7a0ad55701378b345f18277735df3511cce965bc889035e74f
4
- data.tar.gz: 91c392bded5bbd0897222859feab4d68e8c0d3064d4054e6b75509a325ced2d0
3
+ metadata.gz: ad97aecf5e4f97baffb4f944fa8f8a62b449846714e1c2dd2e8bbdc9a167ee22
4
+ data.tar.gz: f638754ff073096c6904db2e5d394413e2f1c579966b97af831cfe93ae91af51
5
5
  SHA512:
6
- metadata.gz: 1ea253c903e6a90eb3754ed9f4a586adcc7339c831d9623401cc4bb53256359c81e069bba4067a12379da350fbf354b50bfd14420ae0aa75c3841c74942ae5f2
7
- data.tar.gz: 8441b41ae22a25f1bd29514fbdcb425b4bbd56b591da6904df0c9ad070a7ac830b1eb9338783a8c751d8f648db4826d69b7755a0f42cd320baaf8e3ebeb7c628
6
+ metadata.gz: 9efd42b242a8c94f0a4372689205e736819ff0fb8e75fa29e95e708899adefacbefec43af0987449fbd3fd766dbb78b1c3f750d51d3141ee4bcb353d08cf9490
7
+ data.tar.gz: b871fd59eabc84e1f135a4638527f7042b48ee033f17f7bd17378ab7002308e81202c37269912ca5883af30f06c1a7a6a8dc4d121d10573225cb464226f91251
data/CHANGELOG.md CHANGED
@@ -1,4 +1,28 @@
1
- ## [Unreleased]
1
+ ## [0.6.0] - 2026-06-20
2
+
3
+ ### Added
4
+ - Property options for richer schemas: `default`, `nullable`, `read_only`, and `write_only` on any `property` in a request body, response, or shared schema — emitted as OpenAPI `default`, `nullable`, `readOnly`, and `writeOnly`. Falsy values like `default: false` and `default: 0` are preserved
5
+ - Response headers: declare them inside a `response` block with `header "X-RateLimit-Remaining", type: :integer, description: "..."`, emitted as an OpenAPI `headers` object on that response
6
+ - System Map `uses_schema` edges: documented endpoints that reference a shared schema (`schema ref: :User`) are now linked to that schema node in the graph
7
+ - `TROUBLESHOOTING.md` covering common questions (missing routes, ignored options, AI setup, production exposure)
8
+ - README section on restricting access to the docs endpoints in production
9
+
10
+ ### Changed
11
+ - README documents the new property options and response headers
12
+
13
+ ### Removed
14
+ - The AI "Explain section" / system insights feature and its endpoint (`/api-docs/system/insights`). It was unauthenticated — exposing an outbound, billable AI call and rendering AI output without escaping — so it has been removed. The rest of the System Map (diagram, docs view, search, theming, PNG export) is unchanged, and `rails docit:autodoc` is unaffected
15
+
16
+ ## [0.5.0] - 2026-05-31
17
+
18
+ ### Added
19
+ - **System Map**: a local, deterministic architecture graph at `/api-docs/system` (JSON at `/api-docs/system.json`), built from Rails routes, controllers, actions, Docit docs coverage, schemas, models, and source-derived service/job/mailer nodes — no external service required
20
+ - System Map navigation alongside the Scalar and Swagger UIs
21
+ - Light and dark themes for the System Map (light by default), with a toolbar toggle persisted across visits
22
+ - **Diagram view**: interactive architecture graph with drag-to-arrange, scroll-to-zoom, pan, fit-to-screen, and PNG export; click a node to inspect its connections, with neighbouring nodes highlighted; `/` focuses node search
23
+ - Endpoints-section filter for the diagram (Users, Orders, …) that narrows the graph to one resource and everything it touches
24
+ - **Docs view**: a request/response reference grouped by resource, with human-readable endpoint titles derived from doc summaries (falling back to REST conventions), a documentation-coverage indicator per section, and a detail panel showing parameters, request body, and responses
25
+ - AI section explanations in the Docs view: "Explain section" summarises how a resource's endpoints work together, gated by a coverage warning so undocumented sections don't silently spend tokens
2
26
 
3
27
  ## [0.4.0] - 2026-04-18
4
28
 
data/README.md CHANGED
@@ -11,7 +11,51 @@ Decorator-style API documentation for Ruby on Rails. Write OpenAPI 3.0.3 docs wi
11
11
  ### Swagger
12
12
  ![Swagger UI](docs/images/swagger_image.png)
13
13
 
14
- > **Full documentation:** [docitruby.dev/docs](https://docitruby.dev/docs)
14
+ > **Full documentation:** [doc-it.dev/docs](https://doc-it.dev/docs)
15
+
16
+ ## Table Of Contents
17
+
18
+ - Getting started
19
+ - [Installation](#installation)
20
+ - [Configuration](#configuration)
21
+ - [Usage](#usage)
22
+ - Documentation styles
23
+ - [Style 1: Inline (simple APIs)](#style-1-inline-simple-apis)
24
+ - [Style 2: Separate doc files (recommended for larger APIs)](#style-2-separate-doc-files-recommended-for-larger-apis)
25
+ - Endpoint DSL reference
26
+ - [Endpoint documentation DSL](#endpoint-documentation-dsl)
27
+ - [Request bodies](#request-bodies)
28
+ - [Path parameters](#path-parameters)
29
+ - [Enums](#enums)
30
+ - [Property options](#property-options)
31
+ - [Response headers](#response-headers)
32
+ - [Security](#security)
33
+ - [Deprecated endpoints](#deprecated-endpoints)
34
+ - [Nested objects and arrays](#nested-objects-and-arrays)
35
+ - [Response examples](#response-examples)
36
+ - [Shared schemas (`$ref`)](#shared-schemas-ref)
37
+ - [File uploads](#file-uploads)
38
+ - AI documentation
39
+ - [AI Automatic Documentation](#ai-automatic-documentation)
40
+ - [Quick start (included in install)](#quick-start-included-in-install)
41
+ - [Standalone commands](#standalone-commands)
42
+ - [Supported providers](#supported-providers)
43
+ - [What the AI generates](#what-the-ai-generates)
44
+ - Runtime and development
45
+ - [Documentation UIs](#documentation-uis)
46
+ - [System Map](#system-map)
47
+ - [How it works](#how-it-works)
48
+ - [Mounting at a different path](#mounting-at-a-different-path)
49
+ - [Restricting access in production](#restricting-access-in-production)
50
+ - [JSON spec only](#json-spec-only)
51
+ - [Development](#development)
52
+ - [Contributing](#contributing)
53
+ - [License](#license)
54
+ - Project docs
55
+ - [CHANGELOG](CHANGELOG.md)
56
+ - [TROUBLESHOOTING](TROUBLESHOOTING.md)
57
+ - [CONTRIBUTING](CONTRIBUTING.md)
58
+ - [CODE OF CONDUCT](CODE_OF_CONDUCT.md)
15
59
 
16
60
  ## Installation
17
61
 
@@ -39,6 +83,8 @@ The install generator does everything in one step:
39
83
 
40
84
  Visit `/api-docs` to see your interactive API documentation (Scalar by default, Swagger UI also available at `/api-docs/swagger`).
41
85
 
86
+ If you choose AI setup, Docit stores your provider config in `.docit_ai.yml` with restricted file permissions and adds that file to `.gitignore` when possible.
87
+
42
88
  ## Configuration
43
89
 
44
90
  Edit `config/initializers/docit.rb`:
@@ -48,19 +94,39 @@ Docit.configure do |config|
48
94
  config.title = "My API"
49
95
  config.version = "1.0.0"
50
96
  config.description = "Backend API documentation"
51
- config.default_ui = :scalar # :scalar (default) or :swagger
52
97
 
53
- config.auth :bearer # Bearer token (JWT)
98
+ # Documentation UI: :scalar (default) or :swagger
99
+ config.default_ui = :scalar
100
+
101
+ # Authentication: pick one (or multiple):
102
+ config.auth :bearer # Bearer token (JWT by default)
103
+ config.auth :basic # HTTP Basic
104
+ config.auth :api_key, name: "X-API-Key", # API key in header
105
+ location: "header"
106
+
107
+ # Tag descriptions (shown in the documentation sidebar):
54
108
  config.tag "Users", description: "User account management"
109
+ config.tag "Auth", description: "Authentication endpoints"
110
+
111
+ # Server URLs (shown in the server dropdown):
55
112
  config.server "https://api.example.com", description: "Production"
113
+ config.server "https://staging.example.com", description: "Staging"
114
+ config.server "http://localhost:3000", description: "Development"
115
+
116
+ # License information:
117
+ config.license name: "MIT", url: "https://opensource.org/licenses/MIT"
118
+
119
+ # Contact information:
120
+ config.contact name: "API Team", email: "api@example.com", url: "https://example.com/support"
121
+
122
+ # Terms of service:
123
+ config.terms_of_service "https://example.com/tos"
56
124
  end
57
125
  ```
58
126
 
59
- See the [full configuration reference](https://docitruby.dev/docs/configuration) for all options including `license`, `contact`, `terms_of_service`, multiple auth schemes, and server URLs.
60
-
61
- ## Quick Start
127
+ ## Usage
62
128
 
63
- Docit supports two styles. Choose whichever fits your project or mix both.
129
+ Docit supports two styles for documenting endpoints. Choose whichever fits your project or mix both.
64
130
 
65
131
  ### Style 1: Inline (simple APIs)
66
132
 
@@ -73,7 +139,6 @@ class Api::V1::UsersController < ApplicationController
73
139
  tags "Users"
74
140
  response 200, "Users retrieved"
75
141
  end
76
-
77
142
  def index
78
143
  # your code
79
144
  end
@@ -93,62 +158,451 @@ module Api::V1::UsersDocs
93
158
 
94
159
  doc :index do
95
160
  summary "List all users"
161
+ description "Returns a paginated list of users"
96
162
  tags "Users"
97
163
 
164
+ parameter :page, location: :query, type: :integer, description: "Page number"
165
+
98
166
  response 200, "Users retrieved" do
99
167
  property :users, type: :array, items: :object do
100
168
  property :id, type: :integer, example: 1
101
169
  property :email, type: :string, example: "user@example.com"
102
170
  end
171
+ property :total, type: :integer, example: 42
172
+ end
173
+ end
174
+
175
+ doc :create do
176
+ summary "Create a user"
177
+ tags "Users"
178
+
179
+ request_body required: true do
180
+ property :email, type: :string, required: true
181
+ property :password, type: :string, required: true, format: :password
182
+ end
183
+
184
+ response 201, "User created" do
185
+ property :id, type: :integer
186
+ end
187
+
188
+ response 422, "Validation failed" do
189
+ property :errors, type: :object do
190
+ property :email, type: :array, items: :string
191
+ end
103
192
  end
104
193
  end
105
194
  end
106
- ```
107
195
 
108
- ```ruby
109
- # app/controllers/api/v1/users_controller.rb
196
+ # app/controllers/api/v1/users_controller.rb — stays clean!
110
197
  class Api::V1::UsersController < ApplicationController
111
198
  use_docs Api::V1::UsersDocs
112
199
 
113
200
  def index
114
201
  # pure business logic
115
202
  end
203
+
204
+ def create
205
+ # pure business logic
206
+ end
207
+ end
208
+ ```
209
+
210
+ You can also mix both styles — use `use_docs` for most actions and add inline `doc_for` for one-offs:
211
+
212
+ ```ruby
213
+ class Api::V1::UsersController < ApplicationController
214
+ use_docs Api::V1::UsersDocs # loads :index and :create from doc file
215
+
216
+ doc_for :destroy do # inline doc for this one action
217
+ summary "Delete user"
218
+ tags "Users"
219
+ response 204, "Deleted"
220
+ end
221
+
222
+ def index; end
223
+ def create; end
224
+ def destroy; end
225
+ end
226
+ ```
227
+
228
+ ### Endpoint documentation DSL
229
+
230
+ The following examples work in both `doc_for` blocks and `doc` blocks.
231
+
232
+ ### Request bodies
233
+
234
+ ```ruby
235
+ doc_for :create do
236
+ summary "Create a user"
237
+ tags "Users"
238
+
239
+ request_body required: true do
240
+ property :email, type: :string, required: true, example: "user@example.com"
241
+ property :password, type: :string, required: true, format: :password
242
+ property :name, type: :string, example: "Jane Doe"
243
+ property :profile, type: :object do
244
+ property :bio, type: :string
245
+ property :avatar_url, type: :string, format: :uri
246
+ end
247
+ end
248
+
249
+ response 201, "User created" do
250
+ property :id, type: :integer, example: 1
251
+ property :email, type: :string, example: "user@example.com"
252
+ end
253
+
254
+ response 422, "Validation failed" do
255
+ property :errors, type: :object do
256
+ property :email, type: :array, items: :string
257
+ end
258
+ end
259
+ end
260
+ def create
261
+ # your code
262
+ end
263
+ ```
264
+
265
+ ### Path parameters
266
+
267
+ ```ruby
268
+ doc_for :show do
269
+ summary "Get a user"
270
+ tags "Users"
271
+
272
+ parameter :id, location: :path, type: :integer, required: true, description: "User ID"
273
+
274
+ response 200, "User found" do
275
+ property :id, type: :integer, example: 1
276
+ property :email, type: :string
277
+ property :name, type: :string
278
+ end
279
+
280
+ response 404, "User not found" do
281
+ property :error, type: :string, example: "Not found"
282
+ end
283
+ end
284
+ def show
285
+ # your code
286
+ end
287
+ ```
288
+
289
+ ### Enums
290
+
291
+ ```ruby
292
+ doc_for :index do
293
+ summary "List orders"
294
+ tags "Orders"
295
+
296
+ parameter :status, location: :query, type: :string,
297
+ enum: %w[pending shipped delivered],
298
+ description: "Filter by status"
299
+
300
+ response 200, "Orders list" do
301
+ property :orders, type: :array do
302
+ property :id, type: :integer
303
+ property :status, type: :string, enum: %w[pending shipped delivered]
304
+ end
305
+ end
306
+ end
307
+ ```
308
+
309
+ ### Property options
310
+
311
+ Any `property` (in a request body, response, or shared schema) accepts these OpenAPI 3.0.3 options:
312
+
313
+ ```ruby
314
+ request_body required: true do
315
+ property :id, type: :integer, read_only: true # readOnly: present in responses, not accepted as input
316
+ property :password, type: :string, write_only: true # writeOnly: accepted as input, never returned
317
+ property :role, type: :string, default: "member" # default value
318
+ property :nickname, type: :string, nullable: true # may be null
319
+ property :active, type: :boolean, default: false # falsy defaults are preserved
320
+ end
321
+ ```
322
+
323
+ These map to `readOnly`, `writeOnly`, `default`, and `nullable` in the generated spec.
324
+
325
+ ### Response headers
326
+
327
+ Document the headers a response returns with `header` inside a `response` block:
328
+
329
+ ```ruby
330
+ response 200, "Orders list" do
331
+ header "X-Total-Count", type: :integer, description: "Total orders available"
332
+ header "X-RateLimit-Remaining", type: :integer, description: "Requests left in the window"
333
+
334
+ property :orders, type: :array do
335
+ property :id, type: :integer
336
+ end
337
+ end
338
+ ```
339
+
340
+ ### Security
341
+
342
+ Mark endpoints as requiring authentication:
343
+
344
+ ```ruby
345
+ doc_for :destroy do
346
+ summary "Delete a user"
347
+ tags "Users"
348
+ security :bearer_auth # references the scheme from your config
349
+
350
+ response 204, "User deleted"
351
+ response 401, "Unauthorized"
352
+ end
353
+ ```
354
+
355
+ ### Deprecated endpoints
356
+
357
+ ```ruby
358
+ doc_for :legacy_search do
359
+ summary "Search (legacy)"
360
+ tags "Search"
361
+ deprecated
362
+
363
+ response 200, "Results"
364
+ end
365
+ ```
366
+
367
+ ### Nested objects and arrays
368
+
369
+ ```ruby
370
+ response 200, "Success" do
371
+ property :user, type: :object do
372
+ property :id, type: :integer
373
+ property :name, type: :string
374
+ property :addresses, type: :array do
375
+ property :street, type: :string
376
+ property :city, type: :string
377
+ property :zip, type: :string
378
+ end
379
+ end
380
+ end
381
+ ```
382
+
383
+ ### Response examples
384
+
385
+ ```ruby
386
+ response 200, "User found" do
387
+ property :id, type: :integer
388
+ property :email, type: :string
389
+
390
+ example "admin_user",
391
+ { id: 1, email: "admin@example.com" },
392
+ description: "An admin user"
393
+
394
+ example "regular_user",
395
+ { id: 2, email: "user@example.com" },
396
+ description: "A regular user"
397
+ end
398
+ ```
399
+
400
+ ### Shared schemas (`$ref`)
401
+
402
+ Define reusable schemas once and reference them across multiple endpoints:
403
+
404
+ ```ruby
405
+ # In config/initializers/docit.rb or a dedicated file:
406
+ Docit.define_schema :User do
407
+ property :id, type: :integer, example: 1
408
+ property :email, type: :string, example: "user@example.com"
409
+ property :name, type: :string, example: "Jane Doe"
410
+ property :address, type: :object do
411
+ property :street, type: :string
412
+ property :city, type: :string
413
+ end
414
+ end
415
+
416
+ Docit.define_schema :Error do
417
+ property :error, type: :string, example: "Not found"
418
+ property :details, type: :array, items: :string
419
+ end
420
+ ```
421
+
422
+ Reference them in any endpoint with `schema ref:`:
423
+
424
+ ```ruby
425
+ doc_for :show do
426
+ summary "Get user"
427
+ tags "Users"
428
+
429
+ response 200, "User found" do
430
+ schema ref: :User
431
+ end
432
+
433
+ response 404, "Not found" do
434
+ schema ref: :Error
435
+ end
436
+ end
437
+
438
+ doc_for :create do
439
+ summary "Create user"
440
+ tags "Users"
441
+
442
+ request_body required: true do
443
+ schema ref: :User
444
+ end
445
+
446
+ response 201, "Created" do
447
+ schema ref: :User
448
+ end
449
+ end
450
+ ```
451
+
452
+ This outputs `$ref: '#/components/schemas/User'` in the spec — Swagger UI resolves it automatically.
453
+
454
+ ### File uploads
455
+
456
+ Use `type: :file` with `content_type: "multipart/form-data"` for file upload endpoints:
457
+
458
+ ```ruby
459
+ doc_for :upload_avatar do
460
+ summary "Upload avatar"
461
+ tags "Users"
462
+
463
+ request_body required: true, content_type: "multipart/form-data" do
464
+ property :avatar, type: :file, required: true, description: "Avatar image"
465
+ property :caption, type: :string
466
+ end
467
+
468
+ response 201, "Avatar uploaded" do
469
+ property :url, type: :string, format: :uri
470
+ end
116
471
  end
117
472
  ```
118
473
 
119
- See the [full DSL reference](https://docitruby.dev/docs/dsl-reference) for request bodies, path parameters, enums, security, nested objects, file uploads, shared schemas, and more.
474
+ `type: :file` maps to `{ type: "string", format: "binary" }` in the OpenAPI spec.
475
+
476
+ ## AI Automatic Documentation
477
+
478
+ Docit can generate complete API documentation using AI. This works with OpenAI, Anthropic, or Groq (free tier available).
120
479
 
121
- ## AI Documentation
480
+ ### Quick start (included in install)
122
481
 
123
- Docit can generate complete API documentation using AI. Works with OpenAI, Anthropic, or Groq (free tier available).
482
+ When you run `rails generate docit:install` and choose option 1 (AI automatic docs), everything is set up automatically — provider configuration, doc generation, controller wiring, and tag injection.
124
483
 
125
- When you run `rails generate docit:install` and choose AI automatic docs, everything is set up automatically provider configuration, doc generation, controller wiring, and tag injection.
484
+ Before the first AI request, Docit warns that your controller source code will be sent to the selected provider and asks for confirmation in interactive terminals.
485
+
486
+ ### Standalone commands
487
+
488
+ You can also set up AI docs separately:
126
489
 
127
490
  ```bash
128
- # Or set up AI docs separately:
491
+ # Configure your AI provider (one-time setup)
129
492
  rails generate docit:ai_setup
493
+
494
+ # Generate docs for all undocumented endpoints
130
495
  rails docit:autodoc
131
496
 
132
- # Preview without writing files:
497
+ # Generate docs for a specific controller
498
+ rails docit:autodoc[Api::V1::UsersController]
499
+
500
+ # Preview what would be generated without writing files
133
501
  DRY_RUN=1 rails docit:autodoc
134
502
  ```
135
503
 
136
- See the [full AI documentation guide](https://docitruby.dev/docs/ai-documentation) for provider details, safety considerations, and standalone commands.
504
+ ### Supported providers
505
+
506
+ | Provider | Notes |
507
+ |------------|-------|
508
+ | OpenAI | Requires API key from platform.openai.com |
509
+ | Anthropic | Requires API key from console.anthropic.com |
510
+ | Groq | Free tier at console.groq.com |
511
+
512
+ All providers automatically retry on rate-limit (429) errors with exponential backoff, so free-tier usage works out of the box.
513
+
514
+ AI configuration is stored in `.docit_ai.yml`.
515
+ If your app does not have a `.gitignore`, add `.docit_ai.yml` manually.
516
+
517
+ ### What the AI generates
518
+
519
+ For each undocumented endpoint, Docit:
520
+
521
+ 1. Reads the controller source code
522
+ 2. Inspects the route (HTTP method, path, parameters)
523
+ 3. Writes the generated doc block to `app/docs/`
524
+ 4. Injects `use_docs` into the controller
525
+ 5. Adds tag descriptions to the initializer
526
+
527
+ Do not use AI autodoc on controllers that contain secrets, proprietary business rules, or internal comments you do not want sent to an external provider.
137
528
 
138
529
  ## Documentation UIs
139
530
 
531
+ Docit ships with two documentation UIs, both reading from the same OpenAPI spec:
532
+
140
533
  | Path | UI | Notes |
141
534
  |------|------|-------|
142
535
  | `/api-docs` | Default (Scalar) | Configurable via `config.default_ui` |
143
- | `/api-docs/scalar` | Scalar API Reference | Modern UI with API client, dark mode |
536
+ | `/api-docs/scalar` | Scalar API Reference | Modern UI with built-in API client, dark mode, code samples |
144
537
  | `/api-docs/swagger` | Swagger UI | Classic OpenAPI explorer |
538
+ | `/api-docs/system` | System Map | Local architecture graph for routes, controllers, docs coverage, and app structure |
145
539
  | `/api-docs/spec` | Raw JSON | OpenAPI 3.0.3 spec |
146
540
 
147
- ## How It Works
541
+ Both UIs include a navigation bar to switch between them. Set `config.default_ui = :swagger` to make Swagger the default at `/api-docs`.
542
+
543
+ ## System Map
544
+
545
+ Docit includes a local system map for understanding how your Rails API fits together. It builds a **deterministic** graph from Rails routes, controller actions, Docit docs, schemas, models, and source references — no external service is required to view it.
546
+
547
+ Visit `/api-docs/system` to open it. It has two views, a light/dark theme toggle, and PNG export:
548
+
549
+ - **Diagram** — an interactive architecture graph. Drag nodes to rearrange, scroll to zoom, and click a node to inspect its connections (its neighbours highlight while the rest fade back). Filter to a single resource with the section dropdown, or press `/` to search nodes.
550
+ - **Docs** — a request/response reference grouped by resource. Each endpoint shows a human-readable title, its method and path, parameters, request body, and responses, drawn from your Docit docs. A coverage indicator shows how many endpoints in each section are documented.
551
+
552
+ If you have an AI provider configured, the Docs view's **Explain section** button summarises how a resource's endpoints work together. It warns before running on sections with undocumented endpoints, so documenting first gives a better result.
553
+
554
+ ## How it works
148
555
 
149
556
  1. `doc_for` registers an **Operation** for each controller action in a global **Registry**
150
557
  2. When someone visits `/api-docs/spec`, Docit's **SchemaGenerator** combines all registered operations with your Rails routes (via **RouteInspector**) to produce an OpenAPI 3.0.3 JSON document
151
558
  3. The **Engine** serves the configured documentation UI at `/api-docs`, pointing it at the generated spec
559
+ 4. The **SystemGraph** builds a local architecture graph for `/api-docs/system`
560
+
561
+ The DSL is included in all controllers automatically via a Rails Engine initializer — no manual `include` needed if you're using `ActionController::API` or `ActionController::Base`.
562
+
563
+ ## Mounting at a different path
564
+
565
+ In `config/routes.rb`:
566
+
567
+ ```ruby
568
+ mount Docit::Engine => "/docs" # now at /docs instead of /api-docs
569
+ ```
570
+
571
+ ## Restricting access in production
572
+
573
+ The Docit endpoints (`/api-docs`, `/api-docs/spec`, `/api-docs/system`, `/api-docs/system.json`) are **unauthenticated by default** and expose your full API surface, the OpenAPI spec, and — for the System Map — your app's structure and source file paths. That is convenient in development, but in production you almost always want to gate them.
574
+
575
+ Mount the engine inside an authenticated constraint, or behind whatever auth your app already uses:
576
+
577
+ ```ruby
578
+ # config/routes.rb
579
+
580
+ # Option A — only mount outside production
581
+ mount Docit::Engine => "/api-docs" unless Rails.env.production?
582
+
583
+ # Option B — gate behind an authenticated constraint (e.g. Devise admins)
584
+ authenticate :user, ->(u) { u.admin? } do
585
+ mount Docit::Engine => "/api-docs"
586
+ end
587
+
588
+ # Option C — HTTP Basic auth via a Rack constraint
589
+ admins_only = ->(request) do
590
+ ActiveSupport::SecurityUtils.secure_compare(
591
+ request.authorization.to_s, ENV.fetch("DOCS_AUTH", "")
592
+ )
593
+ end
594
+ constraints(admins_only) { mount Docit::Engine => "/api-docs" }
595
+ ```
596
+
597
+ If you disable the System Map specifically, set `config.system_graph_enabled = false` — `/api-docs/system.json` then returns `404`.
598
+
599
+ ## JSON spec only
600
+
601
+ If you just want the raw OpenAPI JSON (e.g., for code generation):
602
+
603
+ ```
604
+ GET /api-docs/spec
605
+ ```
152
606
 
153
607
  ## Development
154
608
 
@@ -156,7 +610,7 @@ See the [full AI documentation guide](https://docitruby.dev/docs/ai-documentatio
156
610
  git clone https://github.com/S13G/docit.git
157
611
  cd docit
158
612
  bundle install
159
- bundle exec rspec
613
+ bundle exec rspec # run all tests
160
614
  ```
161
615
 
162
616
  ## Contributing
@@ -0,0 +1,57 @@
1
+ # Troubleshooting
2
+
3
+ Common questions and fixes when working with Docit.
4
+
5
+ ## My route isn't showing up in the spec
6
+
7
+ Docit only documents an endpoint if **both** are true:
8
+
9
+ 1. The route exists in `config/routes.rb` (visible in `rails routes`).
10
+ 2. A doc is registered for that controller + action — either inline with `doc_for :action do ... end` or via `use_docs SomeDocs`.
11
+
12
+ A route with no matching `doc_for`/`use_docs` is simply absent from `/api-docs/spec`. It will still appear on the **System Map** (`/api-docs/system`) marked `undocumented`, which is the quickest way to see your coverage gaps.
13
+
14
+ Checklist:
15
+
16
+ - Is the action name spelled exactly the same in the route and in `doc_for`?
17
+ - Is the controller actually loaded? Docit eager-loads controllers when generating the spec, but a controller in a non-standard path may be missed.
18
+ - If using `use_docs`, does the doc module define a `doc :action` block for that action?
19
+
20
+ ## A doc_for option seems to be ignored
21
+
22
+ Docit's DSL methods are explicit. If you mistype one (e.g. `summmary` instead of `summary`), the call currently does nothing rather than raising — so the option silently disappears.
23
+
24
+ Double-check the spelling of DSL methods against the [DSL reference in the README](README.md). The supported response/property options include `summary`, `description`, `tags`, `response`, `request_body`, `parameter`, `property` (with `type`, `format`, `example`, `enum`, `default`, `nullable`, `read_only`, `write_only`), `header`, `schema ref:`, `security`, `deprecated`, and `operation_id`.
25
+
26
+ ## A System Map section says "undocumented" or shows low coverage
27
+
28
+ That section's endpoints have no registered docs. Add `doc_for`/`use_docs` for those actions, or accept the gap — coverage is informational, not an error.
29
+
30
+ ## Schemas aren't linked on the System Map
31
+
32
+ `uses_schema` edges only appear when a documented endpoint references a shared schema with `schema ref: :Name` (in its request body or a response), and that schema is defined with `Docit.define_schema :Name`. A plain inline `property` block does not create a schema node.
33
+
34
+ ## I documented an action twice and my changes are ignored
35
+
36
+ Docit's registry keeps the **first** doc registered for a given controller + action and ignores later ones. So if an action is already documented (e.g. via `use_docs SomeDocs`) and you also add an inline `doc_for :same_action do ... end`, the inline block is silently dropped — the `use_docs` version wins.
37
+
38
+ Document each action in exactly one place. If you need to override a shared doc module for one action, change it in the module rather than re-declaring it on the controller.
39
+
40
+ ## AI autodoc / scaffolding isn't working
41
+
42
+ - Run `rails generate docit:ai_setup` once to configure a provider (OpenAI, Anthropic, or Groq). The key is written to `.docit_ai.yml`, which the generator adds to `.gitignore` — **never commit it.**
43
+ - `rails docit:autodoc` sends controller **source code** to your configured provider. In an interactive terminal it asks for confirmation first; in a non-interactive context (CI, piping) it proceeds without prompting, so only run it where sending source is acceptable.
44
+ - Preview without writing files: `DRY_RUN=1 rails docit:autodoc`.
45
+ - Rate-limit / 429 errors are retried with backoff automatically; a persistent failure usually means an invalid key or an unsupported model name.
46
+
47
+ ## The System Map or docs pages are exposed in production
48
+
49
+ The Docit endpoints are **unauthenticated by default**. They expose your API surface, the OpenAPI spec, and your app structure. In production, gate the engine — see [Restricting access in production](README.md#restricting-access-in-production) in the README. To disable the System Map specifically, set `config.system_graph_enabled = false`.
50
+
51
+ ## Spec generation is slow on a large app
52
+
53
+ Generating the spec eager-loads controllers and walks every route. For very large apps this is a one-time cost per request; put the docs behind a cache or a non-production-only mount if it matters. The System Map graph is rebuilt per request — if that becomes a bottleneck, mount it behind auth and access it sparingly.
54
+
55
+ ## Still stuck?
56
+
57
+ Open an issue at <https://github.com/S13G/docit/issues> with your Docit version, Rails version, and a minimal `doc_for` / route example.