Skip to content

Commit 1ad45bc

Browse files
committed
Publish OpenAPI spec at root
1 parent 71e9bb6 commit 1ad45bc

18 files changed

Lines changed: 28 additions & 95 deletions

File tree

.dockerignore

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ app.json
1313
bin/
1414
coverage/
1515
docs/
16-
!docs/api/
17-
!docs/api/v1/
18-
!docs/api/v1/openapi.yaml
1916
Dockerfile
2017
Procfile
2118
Rakefile

Dockerfile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ COPY --chown=$USER:$USER Gemfile Gemfile.lock app.rb config.ru ./
8383
COPY --chown=$USER:$USER app ./app
8484
COPY --chown=$USER:$USER config ./config
8585
COPY --chown=$USER:$USER public ./public
86-
COPY --chown=$USER:$USER docs/api/v1/openapi.yaml ./docs/api/v1/openapi.yaml
8786
COPY --from=frontend-builder --chown=$USER:$USER /app/frontend/dist ./frontend/dist
8887

8988
CMD ["bundle", "exec", "puma", "-C", "./config/puma.rb"]

Makefile

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,26 +102,26 @@ ready: ## Pre-commit gate (quick checks + RSpec)
102102
yard-verify-public-docs: ## Verify essential YARD docs for all public methods in app/
103103
bundle exec rake yard:verify_public_docs
104104

105-
openapi: ## Regenerate docs/api/v1/openapi.yaml from request specs
105+
openapi: ## Regenerate public/openapi.yaml from request specs
106106
bundle exec rake openapi:generate
107107

108-
openapi-verify: ## Regenerate OpenAPI and fail if docs/api/v1/openapi.yaml or frontend client is stale
108+
openapi-verify: ## Regenerate OpenAPI and fail if public/openapi.yaml or frontend client is stale
109109
bundle exec rake openapi:verify
110110
$(MAKE) openapi-client-verify
111111

112-
openapi-client: ## Generate frontend OpenAPI client/types from docs/api/v1/openapi.yaml
112+
openapi-client: ## Generate frontend OpenAPI client/types from public/openapi.yaml
113113
@cd frontend && npm run openapi:generate
114114

115115
openapi-client-verify: ## Generate frontend OpenAPI client and fail if generated files are stale
116116
@cd frontend && npm run openapi:verify
117117

118-
openapi-lint: openapi-lint-redocly openapi-lint-spectral ## Lint docs/api/v1/openapi.yaml with Redocly and Spectral
118+
openapi-lint: openapi-lint-redocly openapi-lint-spectral ## Lint public/openapi.yaml with Redocly and Spectral
119119

120120
openapi-lint-redocly: ## Lint OpenAPI using Redocly recommended rules
121-
npx --yes @redocly/cli lint --config .redocly.yaml docs/api/v1/openapi.yaml
121+
npx --yes @redocly/cli lint --config .redocly.yaml public/openapi.yaml
122122

123123
openapi-lint-spectral: ## Lint OpenAPI using Spectral OAS rules
124-
npx --yes @stoplight/spectral-cli lint --ruleset .spectral.yaml docs/api/v1/openapi.yaml
124+
npx --yes @stoplight/spectral-cli lint --ruleset .spectral.yaml public/openapi.yaml
125125

126126
openai-lint-spectral: openapi-lint-spectral ## Alias for openapi-lint-spectral
127127

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ For contributors and AI agents changing backend structure, follow the rules in [
8585
| `make lint` | Run all linters. |
8686
| `make lintfix` | Auto-fix lint warnings where possible. |
8787
| `make yard-verify-public-docs` | Enforce typed YARD docs for public methods in `app/`. |
88-
| `make openapi` | Regenerate `docs/api/v1/openapi.yaml` from request specs. |
88+
| `make openapi` | Regenerate `public/openapi.yaml` from request specs. |
8989
| `make openapi-verify` | Regenerate + fail if OpenAPI file is stale. |
9090
| `make clean` | Remove build artefacts. |
9191

Rakefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,14 @@ end
9696
namespace :openapi do
9797
desc 'Generate OpenAPI YAML from request specs'
9898
task :generate do
99-
FileUtils.mkdir_p('docs/api/v1')
100-
FileUtils.rm_f('docs/api/v1/openapi.yaml')
99+
FileUtils.mkdir_p('public')
100+
FileUtils.rm_f('public/openapi.yaml')
101101
sh({ 'OPENAPI' => '1' }, 'bundle exec rspec spec/html2rss/web/api/v1_spec.rb --order defined')
102102
end
103103

104104
desc 'Verify generated OpenAPI YAML is up to date'
105105
task verify: :generate do
106-
sh 'git diff --exit-code -- docs/api/v1/openapi.yaml'
106+
sh 'git diff --exit-code -- public/openapi.yaml'
107107
end
108108
end
109109

app/web/api/v1/root_metadata.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def build(router)
1515
api: {
1616
name: 'html2rss-web API',
1717
description: 'RESTful API for converting websites to RSS feeds',
18-
openapi_url: "#{router.base_url}/api/v1/openapi.yaml"
18+
openapi_url: "#{router.base_url}/openapi.yaml"
1919
},
2020
instance: instance_payload(router)
2121
}

app/web/routes/api_v1/metadata_routes.rb

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ def call(router)
2323
def mount_openapi_spec(router)
2424
router.on 'openapi.yaml' do
2525
router.get do
26-
router.response['Content-Type'] = 'application/yaml'
27-
openapi_spec_contents
26+
router.redirect '/openapi.yaml', 301
2827
end
2928
end
3029
end
@@ -55,29 +54,11 @@ def mount_root(router)
5554
end
5655
end
5756

58-
# @return [String]
59-
def openapi_spec_path
60-
File.expand_path('../../../../docs/api/v1/openapi.yaml', __dir__)
61-
end
62-
6357
# @param router [Roda::RodaRequest]
6458
# @return [String]
6559
def render_root_metadata(router)
6660
JSON.generate(Api::V1::Response.success(data: Api::V1::RootMetadata.build(router)))
6761
end
68-
69-
# @return [String]
70-
def openapi_spec_contents
71-
return File.read(openapi_spec_path) if File.exist?(openapi_spec_path)
72-
73-
<<~YAML
74-
openapi: 3.0.3
75-
info:
76-
title: html2rss-web API
77-
version: 1.0.0
78-
paths: {}
79-
YAML
80-
end
8162
end
8263
end
8364
end

docs/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This is the only hand-written project document in `docs/`.
44

55
Keep this file short, current, and operational. Do not add planning docs, migration diaries, redesign notes, or parallel architecture narratives back into this directory.
66

7-
The only other file that belongs in `docs/` is the generated OpenAPI contract at [`docs/api/v1/openapi.yaml`](/Users/gil/versioned/html2rss/html2rss-web/docs/api/v1/openapi.yaml).
7+
The only generated artifact intentionally exposed by the app is [`public/openapi.yaml`](/Users/gil/versioned/html2rss/html2rss-web/public/openapi.yaml).
88

99
## System Snapshot
1010

@@ -55,7 +55,7 @@ Frontend verification lives at `http://127.0.0.1:4001/` while the dev container
5555

5656
## API Contract Rules
5757

58-
- `docs/api/v1/openapi.yaml` is generated output, not hand-edited design prose.
58+
- `public/openapi.yaml` is generated output, not hand-edited design prose.
5959
- Backend behavior and request specs define the contract.
6060
- Regenerate with `make openapi`.
6161
- Drift must fail with `make openapi-verify`.

frontend/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
"format": "prettier --write .",
1212
"format:check": "prettier --check .",
1313
"typecheck": "tsc -p tsconfig.typecheck.json --noEmit",
14-
"openapi:generate": "openapi-ts -i ../docs/api/v1/openapi.yaml -o src/api/generated -c @hey-api/client-fetch",
15-
"openapi:verify": "openapi-ts -i ../docs/api/v1/openapi.yaml -o src/api/generated -c @hey-api/client-fetch && git diff --exit-code -- src/api/generated",
14+
"openapi:generate": "openapi-ts -i ../public/openapi.yaml -o src/api/generated -c @hey-api/client-fetch",
15+
"openapi:verify": "openapi-ts -i ../public/openapi.yaml -o src/api/generated -c @hey-api/client-fetch && git diff --exit-code -- src/api/generated",
1616
"test": "vitest",
1717
"test:run": "vitest run",
1818
"test:unit": "vitest run --reporter=verbose --config vitest.unit.config.ts",

frontend/src/__tests__/App.contract.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ describe('App contract', () => {
8282
api: {
8383
name: 'html2rss-web API',
8484
description: 'RESTful API for converting websites to RSS feeds',
85-
openapi_url: 'http://example.test/api/v1/openapi.yaml',
85+
openapi_url: 'http://example.test/openapi.yaml',
8686
},
8787
instance: {
8888
feed_creation: {

0 commit comments

Comments
 (0)