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.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/.claude/25-09-01-OPENAPI_IMPLEMENTATION.md +233 -0
  3. data/.claude/25-09-05-RESPONSE_SCHEMA.md +383 -0
  4. data/.claude/25-09-10-OPENAPI_PLAN.md +219 -0
  5. data/.claude/25-10-26-MIDDLEWARE_IMPLEMENTATION.md +230 -0
  6. data/.claude/25-10-26-MIDDLEWARE_PLAN.md +353 -0
  7. data/.claude/25-10-27-BACKGROUND_TASKS_ANALYSIS.md +325 -0
  8. data/.claude/25-10-27-DEPENDENCY_IMPLEMENTATION_SUMMARY.md +325 -0
  9. data/.claude/25-10-27-DEPENDENCY_INJECTION_PLAN.md +753 -0
  10. data/.claude/25-12-24-LIFECYCLE_HOOKS_PLAN.md +421 -0
  11. data/.claude/25-12-24-PUBLISHING_AND_DOGFOODING_PLAN.md +327 -0
  12. data/.claude/25-12-24-TEMPLATE_RENDERING_PLAN.md +704 -0
  13. data/.claude/DECISIONS.md +397 -0
  14. data/.claude/PROJECT_PLAN.md +80 -0
  15. data/.claude/TESTING_PLAN.md +285 -0
  16. data/.claude/TESTING_STATUS.md +157 -0
  17. data/.tool-versions +1 -0
  18. data/AGENTS.md +416 -0
  19. data/CHANGELOG.md +5 -0
  20. data/CODE_OF_CONDUCT.md +132 -0
  21. data/LICENSE.txt +21 -0
  22. data/README.md +660 -0
  23. data/Rakefile +10 -0
  24. data/docs +8 -0
  25. data/docs-site/.gitignore +3 -0
  26. data/docs-site/Gemfile +9 -0
  27. data/docs-site/app.rb +138 -0
  28. data/docs-site/content/essential/handler.md +156 -0
  29. data/docs-site/content/essential/lifecycle.md +161 -0
  30. data/docs-site/content/essential/middleware.md +201 -0
  31. data/docs-site/content/essential/openapi.md +155 -0
  32. data/docs-site/content/essential/routing.md +123 -0
  33. data/docs-site/content/essential/validation.md +166 -0
  34. data/docs-site/content/getting-started/at-glance.md +82 -0
  35. data/docs-site/content/getting-started/key-concepts.md +150 -0
  36. data/docs-site/content/getting-started/quick-start.md +127 -0
  37. data/docs-site/content/index.md +81 -0
  38. data/docs-site/content/patterns/async-operations.md +137 -0
  39. data/docs-site/content/patterns/background-tasks.md +143 -0
  40. data/docs-site/content/patterns/database.md +175 -0
  41. data/docs-site/content/patterns/dependencies.md +141 -0
  42. data/docs-site/content/patterns/deployment.md +212 -0
  43. data/docs-site/content/patterns/error-handling.md +184 -0
  44. data/docs-site/content/patterns/response-schema.md +159 -0
  45. data/docs-site/content/patterns/templates.md +193 -0
  46. data/docs-site/content/patterns/testing.md +218 -0
  47. data/docs-site/mise.toml +2 -0
  48. data/docs-site/public/css/style.css +234 -0
  49. data/docs-site/templates/layouts/docs.html.erb +28 -0
  50. data/docs-site/templates/page.html.erb +3 -0
  51. data/docs-site/templates/partials/_nav.html.erb +19 -0
  52. data/examples/background_tasks_demo.rb +159 -0
  53. data/examples/demo_middleware.rb +55 -0
  54. data/examples/demo_openapi.rb +63 -0
  55. data/examples/dependency_block_demo.rb +150 -0
  56. data/examples/dependency_cleanup_demo.rb +146 -0
  57. data/examples/dependency_injection_demo.rb +200 -0
  58. data/examples/lifecycle_demo.rb +57 -0
  59. data/examples/middleware_demo.rb +74 -0
  60. data/examples/templates/layouts/application.html.erb +66 -0
  61. data/examples/templates/todos/_todo.html.erb +15 -0
  62. data/examples/templates/todos/index.html.erb +12 -0
  63. data/examples/templates_demo.rb +87 -0
  64. data/lib/funapi/application.rb +521 -0
  65. data/lib/funapi/async.rb +57 -0
  66. data/lib/funapi/background_tasks.rb +52 -0
  67. data/lib/funapi/config.rb +23 -0
  68. data/lib/funapi/database/sequel/fibered_connection_pool.rb +87 -0
  69. data/lib/funapi/dependency_wrapper.rb +66 -0
  70. data/lib/funapi/depends.rb +138 -0
  71. data/lib/funapi/exceptions.rb +72 -0
  72. data/lib/funapi/middleware/base.rb +13 -0
  73. data/lib/funapi/middleware/cors.rb +23 -0
  74. data/lib/funapi/middleware/request_logger.rb +32 -0
  75. data/lib/funapi/middleware/trusted_host.rb +34 -0
  76. data/lib/funapi/middleware.rb +4 -0
  77. data/lib/funapi/openapi/schema_converter.rb +85 -0
  78. data/lib/funapi/openapi/spec_generator.rb +179 -0
  79. data/lib/funapi/router.rb +43 -0
  80. data/lib/funapi/schema.rb +65 -0
  81. data/lib/funapi/server/falcon.rb +38 -0
  82. data/lib/funapi/template_response.rb +17 -0
  83. data/lib/funapi/templates.rb +111 -0
  84. data/lib/funapi/version.rb +5 -0
  85. data/lib/funapi.rb +14 -0
  86. data/sig/fun_api.rbs +499 -0
  87. 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