belt 0.2.17 → 0.3.14

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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +226 -0
  3. data/README.md +42 -3
  4. data/lib/belt/action_router.rb +34 -19
  5. data/lib/belt/cli/app_detection.rb +30 -3
  6. data/lib/belt/cli/auth_command.rb +395 -0
  7. data/lib/belt/cli/console_command.rb +17 -2
  8. data/lib/belt/cli/deploy_command.rb +51 -17
  9. data/lib/belt/cli/destroy_command.rb +62 -25
  10. data/lib/belt/cli/doctor_command.rb +166 -22
  11. data/lib/belt/cli/environment_command.rb +12 -0
  12. data/lib/belt/cli/explain_command.rb +112 -0
  13. data/lib/belt/cli/frontend_command.rb +31 -10
  14. data/lib/belt/cli/frontend_deploy_command.rb +110 -21
  15. data/lib/belt/cli/frontend_env_command.rb +56 -19
  16. data/lib/belt/cli/frontend_env_map.rb +30 -10
  17. data/lib/belt/cli/frontend_registry.rb +373 -0
  18. data/lib/belt/cli/frontend_setup_command.rb +71 -5
  19. data/lib/belt/cli/generate_command.rb +61 -42
  20. data/lib/belt/cli/index_command.rb +192 -0
  21. data/lib/belt/cli/lambda_config_command.rb +9 -3
  22. data/lib/belt/cli/routes_command/request_model_inference.rb +131 -0
  23. data/lib/belt/cli/routes_command/route_inference.rb +4 -3
  24. data/lib/belt/cli/routes_command.rb +31 -19
  25. data/lib/belt/cli/server_command.rb +28 -15
  26. data/lib/belt/cli/tables_command.rb +3 -1
  27. data/lib/belt/cli/terraform_command.rb +9 -0
  28. data/lib/belt/cli/views_command.rb +15 -15
  29. data/lib/belt/cli/zip_artifact_builder.rb +199 -0
  30. data/lib/belt/cli.rb +17 -9
  31. data/lib/belt/docs/backups.md +101 -0
  32. data/lib/belt/docs/console.md +65 -0
  33. data/lib/belt/docs/controllers.md +155 -0
  34. data/lib/belt/docs/deployment.md +166 -0
  35. data/lib/belt/docs/frontend.md +103 -0
  36. data/lib/belt/docs/generators.md +137 -0
  37. data/lib/belt/docs/lambda_handler.md +105 -0
  38. data/lib/belt/docs/models.md +160 -0
  39. data/lib/belt/docs/observability.md +94 -0
  40. data/lib/belt/docs/plugins.md +94 -0
  41. data/lib/belt/docs/routing.md +138 -0
  42. data/lib/belt/docs/structure.md +96 -0
  43. data/lib/belt/inflector.rb +8 -0
  44. data/lib/belt/route_dsl.rb +318 -100
  45. data/lib/belt/version.rb +1 -1
  46. data/lib/templates/frontend/react/env.yml.example +2 -2
  47. data/lib/templates/generate/auth/cognito.tf.erb +71 -0
  48. data/lib/templates/generate/auth/cognito_outputs.tf.erb +19 -0
  49. data/lib/templates/generate/auth/frontend/ConfirmEmail.jsx +55 -0
  50. data/lib/templates/generate/auth/frontend/Login.jsx +79 -0
  51. data/lib/templates/generate/auth/frontend/ProtectedRoute.jsx +9 -0
  52. data/lib/templates/generate/auth/frontend/SignUp.jsx +58 -0
  53. data/lib/templates/generate/auth/frontend/apiClient.js +34 -0
  54. data/lib/templates/generate/auth/frontend/auth.css +157 -0
  55. data/lib/templates/generate/auth/frontend/auth.js +121 -0
  56. data/lib/templates/generate/model.rb.erb +4 -6
  57. data/lib/templates/module/frontend.tf.erb +49 -43
  58. data/lib/templates/module/outputs.tf.erb +1 -1
  59. data/lib/templates/new_app/AGENTS.md.erb +170 -20
  60. data/lib/templates/new_app/config/lambda/api.yml.erb +1 -0
  61. data/lib/templates/new_app/config/routes.rb.erb +8 -3
  62. data/lib/templates/new_app/lambda/api.rb.erb +1 -1
  63. metadata +56 -1
@@ -0,0 +1,138 @@
1
+ # Routing
2
+
3
+ Belt routes map HTTP requests to controller actions. Routes are defined in
4
+ `config/routes.rb` using a Ruby DSL that mirrors infrastructure (API Gateway + Lambda).
5
+
6
+ ## Defining Routes
7
+
8
+ ```ruby
9
+ Belt.application.routes.draw do
10
+ gateway :api do
11
+ resources :posts
12
+ resources :comments, only: [:index, :create]
13
+ resource :profile, only: [:show, :update]
14
+ get "health", action: :health
15
+ end
16
+ end
17
+ ```
18
+
19
+ ## Route DSL Keywords
20
+
21
+ | Keyword | Purpose | Creates Lambda? |
22
+ |---------|---------|-----------------|
23
+ | `gateway` | Creates an API Gateway + default Lambda | Yes |
24
+ | `function` | Routes to a different Lambda (overrides gateway default) | Yes |
25
+ | `namespace` | Adds path prefix + controller module nesting | No |
26
+ | `scope` | Flexible path/module/auth grouping | No |
27
+
28
+ ## How `resources` Maps to Verbs
29
+
30
+ `resources :posts` generates:
31
+
32
+ | Verb | Path | Action |
33
+ |------|------|--------|
34
+ | GET | /posts | index |
35
+ | POST | /posts | create |
36
+ | GET | /posts/{post_id} | show |
37
+ | PUT | /posts/{post_id} | update |
38
+ | DELETE | /posts/{post_id} | destroy |
39
+
40
+ **Note:** Belt uses PUT, not PATCH, for updates.
41
+
42
+ Use `only:` or `except:` to limit generated routes:
43
+
44
+ ```ruby
45
+ resources :posts, only: [:index, :show, :create]
46
+ resources :comments, except: [:destroy]
47
+ ```
48
+
49
+ ## Singular Resources
50
+
51
+ `resource :profile` (no `:id` in the path):
52
+
53
+ | Verb | Path | Action |
54
+ |------|------|--------|
55
+ | GET | /profile | show |
56
+ | PUT | /profile | update |
57
+ | POST | /profile | create |
58
+ | DELETE | /profile | destroy |
59
+
60
+ ## Namespace and Scope
61
+
62
+ ```ruby
63
+ gateway :api do
64
+ # Namespace: adds path prefix AND controller module
65
+ namespace :admin do
66
+ resources :users # → /admin/users → Admin::UsersController
67
+ end
68
+
69
+ # Scope: flexible grouping without full nesting
70
+ scope path: 'v2', module: 'legacy' do
71
+ resources :widgets # → /v2/widgets → Legacy::WidgetsController
72
+ end
73
+ end
74
+ ```
75
+
76
+ ## Multiple Lambdas
77
+
78
+ Use `function` when routes should be handled by a separate Lambda:
79
+
80
+ ```ruby
81
+ gateway :api do
82
+ resources :posts # → handled by "api" Lambda
83
+
84
+ function :worker do
85
+ resources :jobs # → handled by "worker" Lambda
86
+ end
87
+ end
88
+ ```
89
+
90
+ ## Authentication
91
+
92
+ ```ruby
93
+ gateway :api, auth: :cognito do
94
+ resources :posts # requires cognito auth
95
+ get "health", action: :health, auth: :none # public
96
+ end
97
+ ```
98
+
99
+ ## Table Access
100
+
101
+ Declare which DynamoDB tables a route accesses (used by Terraform for IAM):
102
+
103
+ ```ruby
104
+ resources :posts, tables: [:posts, :comments]
105
+ ```
106
+
107
+ ## Inspecting Routes
108
+
109
+ ```bash
110
+ belt routes # display all routes
111
+ belt routes -g posts # filter by pattern
112
+ belt routes -f json # machine-readable output
113
+ belt routes --namespace api # generate Ruby route manifest
114
+ ```
115
+
116
+ ## Runtime Routing
117
+
118
+ The Lambda entry point uses `Belt::ActionRouter` with the generated route manifest:
119
+
120
+ ```ruby
121
+ require "belt"
122
+ include Belt::LambdaHandler
123
+
124
+ ROUTER = Belt::ActionRouter.new(routes: Routes::API, gateway: "api")
125
+
126
+ def execute(path:, body:, event:)
127
+ ROUTER.route(event: event, body: body)
128
+ end
129
+ ```
130
+
131
+ The router matches the incoming HTTP method + path against the manifest and
132
+ dispatches to the appropriate controller and action.
133
+
134
+ ## See Also
135
+
136
+ - `belt explain controllers` — how controllers handle requests
137
+ - `belt explain deployment` — how routes become infrastructure
138
+ - `belt routes --help` — full CLI options
@@ -0,0 +1,96 @@
1
+ # Project Structure
2
+
3
+ A Belt application follows a conventional directory layout. Understanding
4
+ this structure helps you navigate and extend the app effectively.
5
+
6
+ ## Standard Layout
7
+
8
+ ```
9
+ my-app/
10
+ ├── lambda/ # Application code (deployed to Lambda)
11
+ │ ├── api.rb # Lambda entry point
12
+ │ ├── config/
13
+ │ │ └── environment.rb # App boot file (models, libs, AWS setup)
14
+ │ ├── controllers/
15
+ │ │ ├── application_controller.rb
16
+ │ │ └── my_app/ # Namespaced controllers
17
+ │ │ ├── posts_controller.rb
18
+ │ │ └── admin/
19
+ │ │ └── users_controller.rb
20
+ │ ├── models/
21
+ │ │ ├── application_record.rb # Base model class
22
+ │ │ ├── post.rb
23
+ │ │ └── concerns/ # Shared model behavior
24
+ │ ├── lib/
25
+ │ │ └── routes/ # Auto-generated route manifests
26
+ │ │ └── api_routes.rb
27
+ │ └── Gemfile # Lambda-specific dependencies
28
+ ├── config/
29
+ │ ├── routes.rb # Route definitions (DSL)
30
+ │ ├── contracts.rb # API request/response contracts
31
+ │ └── lambda/ # Per-lambda configuration
32
+ │ └── api.yml # Timeout, memory, env vars
33
+ ├── infrastructure/
34
+ │ ├── modules/ # Shared Terraform modules
35
+ │ │ └── main/
36
+ │ ├── schema.tf.rb # DynamoDB table schema (Ruby DSL)
37
+ │ ├── dev01/ # Per-environment Terraform
38
+ │ │ ├── main.tf
39
+ │ │ ├── variables.tf
40
+ │ │ ├── terraform.tfvars
41
+ │ │ ├── backend.tf
42
+ │ │ └── outputs.tf
43
+ │ └── prod/
44
+ │ └── ...
45
+ ├── frontend/ # Optional frontend (React/Vue/Svelte)
46
+ ├── config/frontends.yml # Optional: multiple named frontends
47
+ ├── Gemfile # Project-level dependencies (CLI, dev tools)
48
+ ├── Rakefile # Rake tasks
49
+ ├── AGENTS.md # AI agent guide
50
+ └── .gitignore
51
+ ```
52
+
53
+ ## Key Files
54
+
55
+ ### `lambda/api.rb` — Lambda Entry Point
56
+
57
+ The file AWS Lambda invokes. Includes `Belt::LambdaHandler` and defines `execute`.
58
+
59
+ ### `lambda/config/environment.rb` — Boot File
60
+
61
+ Loaded by both Lambda and `belt console`. Sets up AWS clients, requires models,
62
+ configures the app. Everything your app needs to run.
63
+
64
+ ### `config/routes.rb` — Route Definitions
65
+
66
+ The Ruby DSL that defines your API. Read by both the Conveyor Belt Terraform
67
+ provider (for infrastructure) and `belt routes` (for manifests).
68
+
69
+ ### `config/lambda/api.yml` — Lambda Config
70
+
71
+ Per-function settings: handler path, runtime, timeout, memory, environment
72
+ variables, layers, triggers.
73
+
74
+ ### `infrastructure/schema.tf.rb` — Table Schema
75
+
76
+ DynamoDB table definitions in Ruby DSL. Used by `belt setup tables` to generate
77
+ Terraform resources.
78
+
79
+ ## Conventions
80
+
81
+ - **Controller namespacing**: Controllers live under `lambda/controllers/<app_name>/`
82
+ to avoid conflicts across modules.
83
+ - **Route manifests**: Generated files in `lambda/lib/routes/` — don't edit manually.
84
+ Regenerate with `belt routes --namespace <name>`.
85
+ - **Two Gemfiles**: Project root Gemfile is for dev tools (belt CLI, rspec).
86
+ `lambda/Gemfile` is what gets packaged into the Lambda.
87
+ - **Config over code**: Lambda configuration (timeout, memory, env vars) goes in
88
+ YAML files, not hardcoded in Terraform.
89
+ - **Frontends**: Default directory is `frontend/`. Multiple SPAs (customer + ops,
90
+ etc.) are declared in `config/frontends.yml`. See `belt explain frontend`.
91
+
92
+ ## See Also
93
+
94
+ - `belt explain routing` — how routes.rb maps to infrastructure
95
+ - `belt explain controllers` — controller conventions
96
+ - `belt explain deployment` — how this structure gets deployed
@@ -42,6 +42,14 @@ module Belt
42
42
  word.to_s.split('_').map(&:capitalize).join
43
43
  end
44
44
 
45
+ # "conversation_id" → "conversationId"
46
+ def camelize_lower(word)
47
+ parts = word.to_s.split('_')
48
+ return word if parts.empty?
49
+
50
+ parts.first + parts[1..].map(&:capitalize).join
51
+ end
52
+
45
53
  # "BlogPost" → "blog_post"
46
54
  def underscore(word)
47
55
  word.to_s