funapi 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/.claude/25-09-01-OPENAPI_IMPLEMENTATION.md +233 -0
- data/.claude/25-09-05-RESPONSE_SCHEMA.md +383 -0
- data/.claude/25-09-10-OPENAPI_PLAN.md +219 -0
- data/.claude/25-10-26-MIDDLEWARE_IMPLEMENTATION.md +230 -0
- data/.claude/25-10-26-MIDDLEWARE_PLAN.md +353 -0
- data/.claude/25-10-27-BACKGROUND_TASKS_ANALYSIS.md +325 -0
- data/.claude/25-10-27-DEPENDENCY_IMPLEMENTATION_SUMMARY.md +325 -0
- data/.claude/25-10-27-DEPENDENCY_INJECTION_PLAN.md +753 -0
- data/.claude/25-12-24-LIFECYCLE_HOOKS_PLAN.md +421 -0
- data/.claude/25-12-24-PUBLISHING_AND_DOGFOODING_PLAN.md +327 -0
- data/.claude/25-12-24-TEMPLATE_RENDERING_PLAN.md +704 -0
- data/.claude/DECISIONS.md +397 -0
- data/.claude/PROJECT_PLAN.md +80 -0
- data/.claude/TESTING_PLAN.md +285 -0
- data/.claude/TESTING_STATUS.md +157 -0
- data/.tool-versions +1 -0
- data/AGENTS.md +416 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE.txt +21 -0
- data/README.md +660 -0
- data/Rakefile +10 -0
- data/docs +8 -0
- data/docs-site/.gitignore +3 -0
- data/docs-site/Gemfile +9 -0
- data/docs-site/app.rb +138 -0
- data/docs-site/content/essential/handler.md +156 -0
- data/docs-site/content/essential/lifecycle.md +161 -0
- data/docs-site/content/essential/middleware.md +201 -0
- data/docs-site/content/essential/openapi.md +155 -0
- data/docs-site/content/essential/routing.md +123 -0
- data/docs-site/content/essential/validation.md +166 -0
- data/docs-site/content/getting-started/at-glance.md +82 -0
- data/docs-site/content/getting-started/key-concepts.md +150 -0
- data/docs-site/content/getting-started/quick-start.md +127 -0
- data/docs-site/content/index.md +81 -0
- data/docs-site/content/patterns/async-operations.md +137 -0
- data/docs-site/content/patterns/background-tasks.md +143 -0
- data/docs-site/content/patterns/database.md +175 -0
- data/docs-site/content/patterns/dependencies.md +141 -0
- data/docs-site/content/patterns/deployment.md +212 -0
- data/docs-site/content/patterns/error-handling.md +184 -0
- data/docs-site/content/patterns/response-schema.md +159 -0
- data/docs-site/content/patterns/templates.md +193 -0
- data/docs-site/content/patterns/testing.md +218 -0
- data/docs-site/mise.toml +2 -0
- data/docs-site/public/css/style.css +234 -0
- data/docs-site/templates/layouts/docs.html.erb +28 -0
- data/docs-site/templates/page.html.erb +3 -0
- data/docs-site/templates/partials/_nav.html.erb +19 -0
- data/examples/background_tasks_demo.rb +159 -0
- data/examples/demo_middleware.rb +55 -0
- data/examples/demo_openapi.rb +63 -0
- data/examples/dependency_block_demo.rb +150 -0
- data/examples/dependency_cleanup_demo.rb +146 -0
- data/examples/dependency_injection_demo.rb +200 -0
- data/examples/lifecycle_demo.rb +57 -0
- data/examples/middleware_demo.rb +74 -0
- data/examples/templates/layouts/application.html.erb +66 -0
- data/examples/templates/todos/_todo.html.erb +15 -0
- data/examples/templates/todos/index.html.erb +12 -0
- data/examples/templates_demo.rb +87 -0
- data/lib/funapi/application.rb +521 -0
- data/lib/funapi/async.rb +57 -0
- data/lib/funapi/background_tasks.rb +52 -0
- data/lib/funapi/config.rb +23 -0
- data/lib/funapi/database/sequel/fibered_connection_pool.rb +87 -0
- data/lib/funapi/dependency_wrapper.rb +66 -0
- data/lib/funapi/depends.rb +138 -0
- data/lib/funapi/exceptions.rb +72 -0
- data/lib/funapi/middleware/base.rb +13 -0
- data/lib/funapi/middleware/cors.rb +23 -0
- data/lib/funapi/middleware/request_logger.rb +32 -0
- data/lib/funapi/middleware/trusted_host.rb +34 -0
- data/lib/funapi/middleware.rb +4 -0
- data/lib/funapi/openapi/schema_converter.rb +85 -0
- data/lib/funapi/openapi/spec_generator.rb +179 -0
- data/lib/funapi/router.rb +43 -0
- data/lib/funapi/schema.rb +65 -0
- data/lib/funapi/server/falcon.rb +38 -0
- data/lib/funapi/template_response.rb +17 -0
- data/lib/funapi/templates.rb +111 -0
- data/lib/funapi/version.rb +5 -0
- data/lib/funapi.rb +14 -0
- data/sig/fun_api.rbs +499 -0
- metadata +220 -0
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
# Publishing and Dogfooding Plan
|
|
2
|
+
|
|
3
|
+
## Date: 2024-12-24
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This document outlines the strategy for publishing FunApi v0.1 and dogfooding it by building a documentation site with the framework itself.
|
|
8
|
+
|
|
9
|
+
## Current State
|
|
10
|
+
|
|
11
|
+
### Completed Features
|
|
12
|
+
- Async-first request handling with Falcon
|
|
13
|
+
- Route definition with path parameters
|
|
14
|
+
- Request validation (body/query) with array support
|
|
15
|
+
- Response schema validation and filtering
|
|
16
|
+
- FastAPI-style error responses
|
|
17
|
+
- OpenAPI/Swagger documentation generation
|
|
18
|
+
- Middleware support (Rack-compatible + built-ins)
|
|
19
|
+
- Dependency injection with cleanup
|
|
20
|
+
- Background tasks (post-response execution)
|
|
21
|
+
- Template rendering (ERB with layouts and partials)
|
|
22
|
+
- Lifecycle hooks (startup/shutdown)
|
|
23
|
+
|
|
24
|
+
### Integration Testing
|
|
25
|
+
- db-postgres integration verified (7 tests passing)
|
|
26
|
+
- Works with testcontainers or existing PostgreSQL
|
|
27
|
+
- Concurrent queries work correctly
|
|
28
|
+
- Lifecycle hooks integrate with DB connections
|
|
29
|
+
|
|
30
|
+
### Known Limitations
|
|
31
|
+
- Background tasks + db-postgres may have fiber conflicts (needs investigation)
|
|
32
|
+
- Path parameter type validation not yet implemented
|
|
33
|
+
- WebSocket support pending
|
|
34
|
+
|
|
35
|
+
## Publishing Strategy
|
|
36
|
+
|
|
37
|
+
### Option A: Publish to RubyGems First (Recommended)
|
|
38
|
+
**Pros:**
|
|
39
|
+
- Standard gem installation works immediately
|
|
40
|
+
- Version tagging and releases tracked
|
|
41
|
+
- Easy for users to try
|
|
42
|
+
|
|
43
|
+
**Cons:**
|
|
44
|
+
- Commits to public API
|
|
45
|
+
- Need proper gemspec metadata
|
|
46
|
+
|
|
47
|
+
**Steps:**
|
|
48
|
+
1. Update gemspec with proper metadata (homepage, source_code_uri, etc.)
|
|
49
|
+
2. Create GitHub repository (if not exists)
|
|
50
|
+
3. Run `gem build fun_api.gemspec`
|
|
51
|
+
4. Run `gem push fun_api-0.1.0.gem`
|
|
52
|
+
5. Tag release on GitHub
|
|
53
|
+
|
|
54
|
+
### Option B: Git-based Installation
|
|
55
|
+
**Pros:**
|
|
56
|
+
- No commitment to RubyGems
|
|
57
|
+
- Can iterate quickly
|
|
58
|
+
- Private until ready
|
|
59
|
+
|
|
60
|
+
**Cons:**
|
|
61
|
+
- Requires git path in Gemfile
|
|
62
|
+
- Less discoverable
|
|
63
|
+
|
|
64
|
+
**Usage:**
|
|
65
|
+
```ruby
|
|
66
|
+
gem 'fun_api', git: 'https://github.com/user/fun_api', branch: 'main'
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Recommendation
|
|
70
|
+
Start with **Option B** for dogfooding, then publish to RubyGems once the docs site is working.
|
|
71
|
+
|
|
72
|
+
## Gemspec Updates Required
|
|
73
|
+
|
|
74
|
+
```ruby
|
|
75
|
+
# fun_api.gemspec updates needed:
|
|
76
|
+
spec.homepage = "https://github.com/gafemoyano/fun_api"
|
|
77
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
|
78
|
+
spec.metadata["source_code_uri"] = "https://github.com/gafemoyano/fun_api"
|
|
79
|
+
spec.metadata["changelog_uri"] = "https://github.com/gafemoyano/fun_api/blob/main/CHANGELOG.md"
|
|
80
|
+
|
|
81
|
+
# Remove the allowed_push_host restriction for public gem
|
|
82
|
+
spec.metadata.delete("allowed_push_host")
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Dogfooding: Documentation Site
|
|
86
|
+
|
|
87
|
+
### Concept
|
|
88
|
+
Build the FunApi documentation site using FunApi itself, demonstrating:
|
|
89
|
+
- HTMX-powered interactive examples
|
|
90
|
+
- Real API endpoints for live demos
|
|
91
|
+
- Template rendering for content pages
|
|
92
|
+
- Lifecycle hooks for initialization
|
|
93
|
+
- Middleware for security/logging
|
|
94
|
+
|
|
95
|
+
### Architecture
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
docs-site/
|
|
99
|
+
├── app.rb # Main FunApi application
|
|
100
|
+
├── Gemfile # Dependencies
|
|
101
|
+
├── templates/
|
|
102
|
+
│ ├── layouts/
|
|
103
|
+
│ │ └── docs.html.erb # Main documentation layout
|
|
104
|
+
│ ├── pages/
|
|
105
|
+
│ │ ├── index.html.erb # Landing page
|
|
106
|
+
│ │ ├── guide.html.erb # Getting started guide
|
|
107
|
+
│ │ └── api.html.erb # API reference
|
|
108
|
+
│ └── partials/
|
|
109
|
+
│ ├── _nav.html.erb # Navigation
|
|
110
|
+
│ ├── _code.html.erb # Code examples
|
|
111
|
+
│ └── _demo.html.erb # Interactive demos
|
|
112
|
+
├── public/
|
|
113
|
+
│ ├── css/
|
|
114
|
+
│ └── js/
|
|
115
|
+
└── content/
|
|
116
|
+
└── guides/ # Markdown content (optional)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Key Features to Demonstrate
|
|
120
|
+
|
|
121
|
+
1. **Template Rendering**
|
|
122
|
+
- Layout with consistent header/footer
|
|
123
|
+
- Partials for reusable components
|
|
124
|
+
- Dynamic content injection
|
|
125
|
+
|
|
126
|
+
2. **HTMX Integration**
|
|
127
|
+
- Live code examples that execute
|
|
128
|
+
- Interactive API explorer
|
|
129
|
+
- Real-time search
|
|
130
|
+
|
|
131
|
+
3. **API Endpoints**
|
|
132
|
+
- `/api/examples/:name` - Run example code
|
|
133
|
+
- `/api/search` - Search documentation
|
|
134
|
+
- `/docs/*` - Static documentation pages
|
|
135
|
+
|
|
136
|
+
4. **Lifecycle Hooks**
|
|
137
|
+
- Load documentation content on startup
|
|
138
|
+
- Warm template cache
|
|
139
|
+
- Initialize search index
|
|
140
|
+
|
|
141
|
+
5. **Middleware**
|
|
142
|
+
- Request logging
|
|
143
|
+
- CORS for API endpoints
|
|
144
|
+
- Caching headers for static content
|
|
145
|
+
|
|
146
|
+
### Sample Implementation
|
|
147
|
+
|
|
148
|
+
```ruby
|
|
149
|
+
# app.rb
|
|
150
|
+
require 'fun_api'
|
|
151
|
+
require 'fun_api/templates'
|
|
152
|
+
require 'fun_api/server/falcon'
|
|
153
|
+
|
|
154
|
+
templates = FunApi::Templates.new(
|
|
155
|
+
directory: 'templates',
|
|
156
|
+
layout: 'layouts/docs.html.erb'
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
DOCS_CONTENT = {}
|
|
160
|
+
|
|
161
|
+
app = FunApi::App.new(
|
|
162
|
+
title: 'FunApi Documentation',
|
|
163
|
+
version: '0.1.0'
|
|
164
|
+
) do |api|
|
|
165
|
+
# Startup: Load documentation content
|
|
166
|
+
api.on_startup do
|
|
167
|
+
puts "Loading documentation..."
|
|
168
|
+
Dir.glob('content/**/*.md').each do |file|
|
|
169
|
+
key = File.basename(file, '.md')
|
|
170
|
+
DOCS_CONTENT[key] = File.read(file)
|
|
171
|
+
end
|
|
172
|
+
puts "Loaded #{DOCS_CONTENT.size} documentation files"
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# Middleware
|
|
176
|
+
api.add_cors(allow_origins: ['*'])
|
|
177
|
+
api.add_request_logger
|
|
178
|
+
|
|
179
|
+
# Documentation pages
|
|
180
|
+
api.get '/' do |_input, _req, _task|
|
|
181
|
+
templates.response('pages/index.html.erb',
|
|
182
|
+
title: 'FunApi - Async-first Ruby Web Framework')
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
api.get '/guide' do |_input, _req, _task|
|
|
186
|
+
templates.response('pages/guide.html.erb',
|
|
187
|
+
title: 'Getting Started',
|
|
188
|
+
content: DOCS_CONTENT['getting-started'])
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Interactive examples API
|
|
192
|
+
api.get '/api/examples/:name' do |input, _req, _task|
|
|
193
|
+
name = input[:path]['name']
|
|
194
|
+
example = load_example(name)
|
|
195
|
+
|
|
196
|
+
if example
|
|
197
|
+
[{code: example[:code], output: run_example(example)}, 200]
|
|
198
|
+
else
|
|
199
|
+
raise FunApi::HTTPException.new(status_code: 404, detail: "Example not found")
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# HTMX partial for code output
|
|
204
|
+
api.post '/api/run' do |input, _req, _task|
|
|
205
|
+
code = input[:body][:code]
|
|
206
|
+
output = safe_eval(code)
|
|
207
|
+
templates.response('partials/_output.html.erb', layout: false, output: output)
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
FunApi::Server::Falcon.start(app, port: 3000)
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Styling Approach
|
|
215
|
+
- Use Tailwind CSS or simple custom CSS
|
|
216
|
+
- Keep it minimal and fast
|
|
217
|
+
- Dark mode support
|
|
218
|
+
- Mobile responsive
|
|
219
|
+
|
|
220
|
+
### Content Structure
|
|
221
|
+
|
|
222
|
+
1. **Landing Page**
|
|
223
|
+
- Hero with code example
|
|
224
|
+
- Feature highlights
|
|
225
|
+
- Quick start snippet
|
|
226
|
+
|
|
227
|
+
2. **Guide Section**
|
|
228
|
+
- Installation
|
|
229
|
+
- Hello World
|
|
230
|
+
- Routes & Parameters
|
|
231
|
+
- Validation
|
|
232
|
+
- Middleware
|
|
233
|
+
- Templates
|
|
234
|
+
- Async Operations
|
|
235
|
+
- Database Integration
|
|
236
|
+
|
|
237
|
+
3. **API Reference**
|
|
238
|
+
- Auto-generated from code
|
|
239
|
+
- Method signatures
|
|
240
|
+
- Examples for each feature
|
|
241
|
+
|
|
242
|
+
4. **Examples**
|
|
243
|
+
- Full working applications
|
|
244
|
+
- HTMX integration
|
|
245
|
+
- Database patterns
|
|
246
|
+
|
|
247
|
+
## Timeline
|
|
248
|
+
|
|
249
|
+
### Phase 1: Publishing Setup (1-2 hours)
|
|
250
|
+
- [ ] Create GitHub repository
|
|
251
|
+
- [ ] Update gemspec metadata
|
|
252
|
+
- [ ] Create v0.1.0 tag
|
|
253
|
+
- [ ] Publish to RubyGems (optional)
|
|
254
|
+
|
|
255
|
+
### Phase 2: Documentation Site MVP (4-6 hours)
|
|
256
|
+
- [ ] Create docs-site directory structure
|
|
257
|
+
- [ ] Implement basic layout and templates
|
|
258
|
+
- [ ] Add landing page with examples
|
|
259
|
+
- [ ] Add getting started guide
|
|
260
|
+
- [ ] Deploy to fly.io or similar
|
|
261
|
+
|
|
262
|
+
### Phase 3: Interactive Features (2-4 hours)
|
|
263
|
+
- [ ] Add HTMX-powered code examples
|
|
264
|
+
- [ ] Implement live API playground
|
|
265
|
+
- [ ] Add search functionality
|
|
266
|
+
|
|
267
|
+
### Phase 4: Polish (2-4 hours)
|
|
268
|
+
- [ ] Complete API documentation
|
|
269
|
+
- [ ] Add more examples
|
|
270
|
+
- [ ] Performance optimization
|
|
271
|
+
- [ ] SEO metadata
|
|
272
|
+
|
|
273
|
+
## Deployment Options
|
|
274
|
+
|
|
275
|
+
### fly.io (Recommended)
|
|
276
|
+
```toml
|
|
277
|
+
# fly.toml
|
|
278
|
+
app = "funapi-docs"
|
|
279
|
+
primary_region = "iad"
|
|
280
|
+
|
|
281
|
+
[build]
|
|
282
|
+
builder = "heroku/buildpacks:22"
|
|
283
|
+
|
|
284
|
+
[http_service]
|
|
285
|
+
internal_port = 3000
|
|
286
|
+
force_https = true
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Docker
|
|
290
|
+
```dockerfile
|
|
291
|
+
FROM ruby:3.2-alpine
|
|
292
|
+
WORKDIR /app
|
|
293
|
+
COPY Gemfile* ./
|
|
294
|
+
RUN bundle install
|
|
295
|
+
COPY . .
|
|
296
|
+
EXPOSE 3000
|
|
297
|
+
CMD ["ruby", "app.rb"]
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Render.com
|
|
301
|
+
- Native Ruby support
|
|
302
|
+
- Easy from GitHub repo
|
|
303
|
+
- Free tier available
|
|
304
|
+
|
|
305
|
+
## Success Criteria
|
|
306
|
+
|
|
307
|
+
1. **Publishing**
|
|
308
|
+
- [ ] Gem installable via `gem install fun_api` or git
|
|
309
|
+
- [ ] Version tagged and documented
|
|
310
|
+
|
|
311
|
+
2. **Documentation Site**
|
|
312
|
+
- [ ] All features documented with examples
|
|
313
|
+
- [ ] Interactive code execution works
|
|
314
|
+
- [ ] Responsive and accessible
|
|
315
|
+
- [ ] < 1 second load time
|
|
316
|
+
|
|
317
|
+
3. **Dogfooding Validation**
|
|
318
|
+
- [ ] No major issues discovered during development
|
|
319
|
+
- [ ] Framework is pleasant to use
|
|
320
|
+
- [ ] Any issues found are documented and fixed
|
|
321
|
+
|
|
322
|
+
## Notes
|
|
323
|
+
|
|
324
|
+
- Keep the docs site simple initially - complexity can come later
|
|
325
|
+
- Focus on getting the getting-started experience right
|
|
326
|
+
- Document any pain points discovered during dogfooding
|
|
327
|
+
- Consider adding a changelog page that pulls from CHANGELOG.md
|