maquina-generators 0.5.0 → 0.7.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 +4 -4
- data/README.md +125 -15
- data/lib/generators/maquina/app/app_generator.rb +9 -4
- data/lib/generators/maquina/app/templates/README.md.erb +6 -4
- data/lib/generators/maquina/app/templates/app/views/home/index.html.erb +18 -5
- data/lib/generators/maquina/app/templates/config/database.yml.tt +12 -0
- data/lib/generators/maquina/clave/clave_generator.rb +48 -0
- data/lib/generators/maquina/clave/templates/app/controllers/registration/verifications_controller.rb.tt +10 -1
- data/lib/generators/maquina/clave/templates/app/controllers/session/verifications_controller.rb.tt +10 -1
- data/lib/generators/maquina/clave/templates/app/models/email_verification.rb.tt +18 -0
- data/lib/generators/maquina/clave/templates/config/locales/clave.en.yml +2 -0
- data/lib/generators/maquina/clave/templates/config/locales/clave.es.yml +2 -0
- data/lib/generators/maquina/csp_reports/USAGE +18 -0
- data/lib/generators/maquina/csp_reports/csp_reports_generator.rb +231 -0
- data/lib/generators/maquina/csp_reports/templates/app/controllers/csp_reports_controller.rb +24 -0
- data/lib/generators/maquina/csp_reports/templates/app/models/security/csp_violation.rb +89 -0
- data/lib/generators/maquina/csp_reports/templates/app/models/security/csp_violation_report.rb +30 -0
- data/lib/generators/maquina/csp_reports/templates/app/views/backstage/security/_csp_violations.html.erb +42 -0
- data/lib/generators/maquina/csp_reports/templates/db/create_csp_violations.rb.tt +23 -0
- data/lib/generators/maquina/mission_control_jobs/mission_control_jobs_generator.rb +32 -1
- data/lib/generators/maquina/mission_control_jobs/templates/app/controllers/backstage_dashboard_controller.rb +47 -0
- data/lib/generators/maquina/mission_control_jobs/templates/app/views/backstage_dashboard/index.html.erb.tt +93 -0
- data/lib/generators/maquina/mission_control_jobs/templates/app/views/layouts/_admin_navigation.html.erb.tt +18 -6
- data/lib/generators/maquina/mission_control_jobs/templates/app/views/layouts/admin.html.erb +21 -0
- data/lib/generators/maquina/rack_attack/USAGE +8 -6
- data/lib/generators/maquina/rack_attack/rack_attack_generator.rb +6 -2
- data/lib/generators/maquina/rack_attack/templates/config/initializers/rack_attack.rb.tt +139 -57
- data/lib/generators/maquina/security/USAGE +15 -0
- data/lib/generators/maquina/security/security_generator.rb +278 -0
- data/lib/generators/maquina/security/templates/app/controllers/backstage/security_controller.rb.tt +45 -0
- data/{test/tmp/app/controllers/backstage_controller.rb → lib/generators/maquina/security/templates/app/controllers/backstage_controller.rb.tt} +0 -1
- data/lib/generators/maquina/security/templates/app/controllers/backstage_dashboard_controller.rb +47 -0
- data/lib/generators/maquina/security/templates/app/models/security/abuse_event.rb +36 -0
- data/lib/generators/maquina/security/templates/app/models/security/abuse_report.rb +112 -0
- data/lib/generators/maquina/security/templates/app/models/security/record.rb +6 -0
- data/lib/generators/maquina/security/templates/app/views/backstage/security/_addresses.html.erb +37 -0
- data/lib/generators/maquina/security/templates/app/views/backstage/security/_blocked.html.erb +53 -0
- data/lib/generators/maquina/security/templates/app/views/backstage/security/_by_day.html.erb +33 -0
- data/lib/generators/maquina/security/templates/app/views/backstage/security/_hosts.html.erb +31 -0
- data/lib/generators/maquina/security/templates/app/views/backstage/security/_paths.html.erb +33 -0
- data/lib/generators/maquina/security/templates/app/views/backstage/security/_recent.html.erb +37 -0
- data/lib/generators/maquina/security/templates/app/views/backstage/security/_utc_time.html.erb +2 -0
- data/lib/generators/maquina/security/templates/app/views/backstage/security/show.html.erb +47 -0
- data/lib/generators/maquina/security/templates/app/views/backstage_dashboard/index.html.erb.tt +93 -0
- data/lib/generators/maquina/security/templates/app/views/layouts/_admin_navigation.html.erb.tt +40 -0
- data/lib/generators/maquina/security/templates/app/views/layouts/admin.html.erb +21 -0
- data/{test/tmp/app/views/layouts/solid_errors/application.html.erb → lib/generators/maquina/security/templates/app/views/layouts/backstage/security.html.erb} +1 -1
- data/lib/generators/maquina/security/templates/config/initializers/rack_attack_events.rb +34 -0
- data/lib/generators/maquina/security/templates/db/security_schema.rb.tt +27 -0
- data/lib/generators/maquina/solid_errors/solid_errors_generator.rb +32 -1
- data/lib/generators/maquina/solid_errors/templates/app/controllers/backstage_dashboard_controller.rb +47 -0
- data/lib/generators/maquina/solid_errors/templates/app/views/backstage_dashboard/index.html.erb.tt +93 -0
- data/lib/generators/maquina/solid_errors/templates/app/views/layouts/_admin_navigation.html.erb.tt +18 -6
- data/lib/generators/maquina/solid_errors/templates/app/views/layouts/admin.html.erb +21 -0
- data/lib/generators/maquina/solid_errors/templates/app/views/solid_errors/error_mailer/error_occurred.html.erb +65 -0
- data/lib/generators/maquina/solid_errors/templates/app/views/solid_errors/error_mailer/error_occurred.text.erb +30 -0
- data/lib/generators/maquina/solid_errors/templates/config/initializers/solid_errors.rb.tt +12 -0
- data/lib/maquina_generators/version.rb +1 -1
- data/test/generators/maquina/app_generator_test.rb +21 -0
- data/test/generators/maquina/clave_generator_test.rb +74 -0
- data/test/generators/maquina/csp_reports_generator_test.rb +151 -0
- data/test/generators/maquina/mission_control_jobs_generator_test.rb +28 -4
- data/test/generators/maquina/rack_attack_generator_test.rb +41 -19
- data/test/generators/maquina/security_generator_test.rb +380 -0
- data/test/generators/maquina/solid_errors_generator_test.rb +59 -4
- data/test/tmp/.gitignore +5 -0
- data/test/tmp/.rubocop.yml +11 -0
- data/test/tmp/.standard.yml +1 -0
- data/test/tmp/Gemfile +12 -2
- data/test/tmp/Procfile.dev +3 -0
- data/test/tmp/README.md +89 -0
- data/test/tmp/app/controllers/home_controller.rb +6 -0
- data/test/tmp/app/javascript/application.js +1 -0
- data/test/tmp/app/views/home/index.html.erb +204 -0
- data/test/tmp/app/views/layouts/application.html.erb +10 -0
- data/test/tmp/config/application.rb +15 -0
- data/test/tmp/config/database.yml +90 -0
- data/test/tmp/config/database.yml.example +90 -0
- data/test/tmp/config/environments/development.rb +8 -0
- data/test/tmp/config/environments/production.rb +6 -0
- data/test/tmp/config/initializers/generators.rb +4 -0
- data/test/tmp/config/routes.rb +1 -1
- metadata +60 -32
- data/test/tmp/app/agents/error_redactor.rb +0 -34
- data/test/tmp/app/agents/errors_query.rb +0 -84
- data/test/tmp/app/agents/failure_triage.rb +0 -21
- data/test/tmp/app/agents/get_exception_tool.rb +0 -26
- data/test/tmp/app/agents/list_failures_tool.rb +0 -20
- data/test/tmp/app/agents/top_exceptions_tool.rb +0 -18
- data/test/tmp/app/helpers/solid_errors_helper.rb +0 -9
- data/test/tmp/app/javascript/controllers/backtrace_filter_controller.js +0 -27
- data/test/tmp/app/javascript/controllers/clipboard_controller.js +0 -36
- data/test/tmp/app/views/layouts/_admin_navigation.html.erb +0 -28
- data/test/tmp/app/views/solid_errors/errors/_actions.html.erb +0 -22
- data/test/tmp/app/views/solid_errors/errors/_delete_button.html.erb +0 -10
- data/test/tmp/app/views/solid_errors/errors/_error_card.html.erb +0 -63
- data/test/tmp/app/views/solid_errors/errors/_resolve_button.html.erb +0 -11
- data/test/tmp/app/views/solid_errors/errors/index.html.erb +0 -37
- data/test/tmp/app/views/solid_errors/errors/show/_actions.html.erb +0 -33
- data/test/tmp/app/views/solid_errors/errors/show/_error_details.html.erb +0 -95
- data/test/tmp/app/views/solid_errors/errors/show/_header.html.erb +0 -18
- data/test/tmp/app/views/solid_errors/errors/show/_properties.html.erb +0 -65
- data/test/tmp/app/views/solid_errors/errors/show.html.erb +0 -23
- data/test/tmp/app/views/solid_errors/occurrences/_backtrace_line.html.erb +0 -27
- data/test/tmp/app/views/solid_errors/occurrences/_collection.html.erb +0 -80
- data/test/tmp/app/views/solid_errors/occurrences/_occurrence.html.erb +0 -129
- data/test/tmp/bin/failures +0 -37
- data/test/tmp/bin/failures-mcp +0 -21
- data/test/tmp/config/initializers/solid_errors.rb +0 -12
|
@@ -96,25 +96,61 @@ class Maquina::Generators::SolidErrorsGeneratorTest < Rails::Generators::TestCas
|
|
|
96
96
|
test "adds route with prefix" do
|
|
97
97
|
run_generator %w[--prefix /admin]
|
|
98
98
|
|
|
99
|
-
assert_file "config/routes.rb", %r{mount SolidErrors::Engine, at: "/admin/
|
|
99
|
+
assert_file "config/routes.rb", %r{mount SolidErrors::Engine, at: "/admin/errors"}
|
|
100
100
|
end
|
|
101
101
|
|
|
102
102
|
test "adds route with custom prefix" do
|
|
103
103
|
run_generator %w[--prefix /backstage]
|
|
104
104
|
|
|
105
|
-
assert_file "config/routes.rb", %r{mount SolidErrors::Engine, at: "/backstage/
|
|
105
|
+
assert_file "config/routes.rb", %r{mount SolidErrors::Engine, at: "/backstage/errors"}
|
|
106
106
|
end
|
|
107
107
|
|
|
108
108
|
test "generates admin navigation partial" do
|
|
109
109
|
run_generator %w[--prefix /admin]
|
|
110
110
|
|
|
111
111
|
assert_file "app/views/layouts/_admin_navigation.html.erb" do |content|
|
|
112
|
-
assert_match(%r{/admin/
|
|
113
|
-
assert_match(%r{/admin/
|
|
112
|
+
assert_match(%r{/admin/errors}, content)
|
|
113
|
+
assert_match(%r{/admin/jobs}, content)
|
|
114
114
|
assert_match(/main_app\.root_path/, content)
|
|
115
115
|
end
|
|
116
116
|
end
|
|
117
117
|
|
|
118
|
+
test "navigation includes an Overview tab pointing at the prefix root" do
|
|
119
|
+
run_generator %w[--prefix /admin]
|
|
120
|
+
|
|
121
|
+
assert_file "app/views/layouts/_admin_navigation.html.erb" do |content|
|
|
122
|
+
assert_match(/<span>Overview<\/span>/, content)
|
|
123
|
+
assert_match(%r{link_to "/admin",}, content)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
test "installs the backstage dashboard" do
|
|
128
|
+
run_generator %w[--prefix /admin]
|
|
129
|
+
|
|
130
|
+
assert_file "app/controllers/backstage_dashboard_controller.rb" do |content|
|
|
131
|
+
assert_match(/class BackstageDashboardController < BackstageController/, content)
|
|
132
|
+
assert_match(/authenticate_or_request_with_http_basic/, content)
|
|
133
|
+
assert_match(/@metrics = \[\]/, content)
|
|
134
|
+
end
|
|
135
|
+
assert_file "app/views/layouts/admin.html.erb", /admin_navigation/
|
|
136
|
+
assert_file "app/views/backstage_dashboard/index.html.erb" do |content|
|
|
137
|
+
assert_match(/Overview/, content)
|
|
138
|
+
assert_match(%r{defined\?\(SolidErrors::Engine\)}, content)
|
|
139
|
+
assert_match(%r{"/admin/errors"}, content)
|
|
140
|
+
assert_match(%r{"/admin/jobs"}, content)
|
|
141
|
+
end
|
|
142
|
+
assert_file "config/routes.rb", %r{get "/admin" => "backstage_dashboard#index"}
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
test "does not duplicate the dashboard route when run twice" do
|
|
146
|
+
run_generator %w[--prefix /admin]
|
|
147
|
+
run_generator %w[--prefix /admin]
|
|
148
|
+
|
|
149
|
+
assert_file "config/routes.rb" do |content|
|
|
150
|
+
assert_equal 1, content.scan("backstage_dashboard#index").length
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
118
154
|
test "does not overwrite existing admin navigation" do
|
|
119
155
|
mkdir_p("app/views/layouts")
|
|
120
156
|
File.write(
|
|
@@ -152,6 +188,25 @@ class Maquina::Generators::SolidErrorsGeneratorTest < Rails::Generators::TestCas
|
|
|
152
188
|
assert_file "app/views/solid_errors/occurrences/_backtrace_line.html.erb"
|
|
153
189
|
end
|
|
154
190
|
|
|
191
|
+
test "copies self-contained mailer templates that avoid dashboard-only helpers" do
|
|
192
|
+
run_generator %w[--prefix /admin]
|
|
193
|
+
|
|
194
|
+
%w[
|
|
195
|
+
app/views/solid_errors/error_mailer/error_occurred.html.erb
|
|
196
|
+
app/views/solid_errors/error_mailer/error_occurred.text.erb
|
|
197
|
+
].each do |path|
|
|
198
|
+
assert_file path do |content|
|
|
199
|
+
# The mailer renders without the BackstageController helpers, so these
|
|
200
|
+
# templates must not reuse the themed dashboard partials or their
|
|
201
|
+
# icon_for/Stimulus dependencies (the cause of the email render loop).
|
|
202
|
+
body = content.gsub(/<%#.*?%>/m, "")
|
|
203
|
+
assert_no_match(/icon_for/, body)
|
|
204
|
+
assert_no_match(/data-controller/, body)
|
|
205
|
+
assert_no_match(%r{render\s+["']solid_errors/}, body)
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
155
210
|
test "copies layout with admin navigation and updated title" do
|
|
156
211
|
run_generator %w[--prefix /admin]
|
|
157
212
|
|
data/test/tmp/.gitignore
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# standard.rb's runner bridge, not custom RuboCop rules.
|
|
2
|
+
#
|
|
3
|
+
# This is the entry point RuboCop (and editors/LSP) need to run the Standard
|
|
4
|
+
# ruleset — all style comes from the `standard` gem via config/base.yml below.
|
|
5
|
+
# Keep this file even though general guidance says "no .rubocop.yml": for
|
|
6
|
+
# standard.rb this IS the runner config, not a custom rule set.
|
|
7
|
+
require:
|
|
8
|
+
- standard
|
|
9
|
+
|
|
10
|
+
inherit_gem:
|
|
11
|
+
standard: config/base.yml
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ruby_version: 3.2
|
data/test/tmp/Gemfile
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
source "https://rubygems.org"
|
|
2
2
|
|
|
3
|
-
gem "
|
|
3
|
+
gem "brakeman", group: :development
|
|
4
4
|
|
|
5
|
-
gem "
|
|
5
|
+
gem "bundle-audit", group: :development
|
|
6
|
+
|
|
7
|
+
gem "letter_opener", group: :development
|
|
8
|
+
|
|
9
|
+
gem "standard", ">= 1.54", group: :development
|
|
10
|
+
|
|
11
|
+
gem "rails-i18n"
|
|
12
|
+
|
|
13
|
+
gem "maquina-components"
|
|
14
|
+
|
|
15
|
+
gem "aws-sdk-s3", group: :production
|
data/test/tmp/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Tmp
|
|
2
|
+
|
|
3
|
+
Built with [maquina.app](https://maquina.app) — production-tested tools for developers who ship alone.
|
|
4
|
+
|
|
5
|
+
## Getting Started
|
|
6
|
+
|
|
7
|
+
### Prerequisites
|
|
8
|
+
|
|
9
|
+
- Ruby 3.2+
|
|
10
|
+
- Rails 8+
|
|
11
|
+
- PostgreSQL (or SQLite for development)
|
|
12
|
+
|
|
13
|
+
### Setup
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bin/setup # Install dependencies and prepare databases
|
|
17
|
+
bin/dev # Start all processes (web, css, solid_queue)
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Your app will be running at **http://localhost:3000**.
|
|
21
|
+
|
|
22
|
+
## What's Included
|
|
23
|
+
|
|
24
|
+
| Feature | Description |
|
|
25
|
+
|---------|-------------|
|
|
26
|
+
| **Background Jobs** | Solid Queue with Mission Control Jobs dashboard |
|
|
27
|
+
| **Error Tracking** | Solid Errors with custom UI |
|
|
28
|
+
| **Rate Limiting** | Rack::Attack with sensible defaults |
|
|
29
|
+
| **UI Components** | Maquina Components (ERB partials + Tailwind + Stimulus) |
|
|
30
|
+
| **Caching** | Solid Cache |
|
|
31
|
+
| **WebSockets** | Solid Cable |
|
|
32
|
+
| **Rich Text** | Action Text |
|
|
33
|
+
| **File Storage** | Active Storage (S3-ready in production) |
|
|
34
|
+
| **Multi-database** | Separate databases for queue, cache, cable, errors, and security |
|
|
35
|
+
|
|
36
|
+
## Development URLs
|
|
37
|
+
|
|
38
|
+
| URL | Description |
|
|
39
|
+
|-----|-------------|
|
|
40
|
+
| http://localhost:3000 | Application |
|
|
41
|
+
| http://localhost:3000/admin | Admin overview |
|
|
42
|
+
| http://localhost:3000/admin/errors | Errors dashboard |
|
|
43
|
+
| http://localhost:3000/admin/jobs | Jobs dashboard |
|
|
44
|
+
| http://localhost:3000/admin/security | Security dashboard |
|
|
45
|
+
|
|
46
|
+
## Scripts
|
|
47
|
+
|
|
48
|
+
- `bin/setup` — Install dependencies and prepare databases
|
|
49
|
+
- `bin/dev` — Start all processes (web, css, solid_queue)
|
|
50
|
+
|
|
51
|
+
## Credentials
|
|
52
|
+
|
|
53
|
+
Edit credentials with:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
bin/rails credentials:edit
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Add backstage credentials for the admin dashboards (overview, errors, jobs, security):
|
|
60
|
+
|
|
61
|
+
```yaml
|
|
62
|
+
backstage:
|
|
63
|
+
username: your_user
|
|
64
|
+
password: your_password
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Maquina Ecosystem
|
|
68
|
+
|
|
69
|
+
### UI Components
|
|
70
|
+
|
|
71
|
+
[Maquina Components](https://maquina.app/documentation/components/) — a library of ERB partials, Tailwind CSS styles, and Stimulus controllers for building consistent, accessible UIs in Rails.
|
|
72
|
+
|
|
73
|
+
### AI Tools
|
|
74
|
+
|
|
75
|
+
Maquina provides a suite of AI-powered tools to accelerate your Rails development:
|
|
76
|
+
|
|
77
|
+
- **Rails MCP Server** — Model Context Protocol server for Rails applications
|
|
78
|
+
- **Rails Simplifier** — simplify and refine Rails code following 37signals patterns
|
|
79
|
+
- **Rails Upgrade Assistant** — comprehensive Rails upgrade reports and migration guides
|
|
80
|
+
- **Maquina UI Standards** — build consistent UIs using maquina_components
|
|
81
|
+
- **Neovim MCP Server** — MCP server for Neovim integration
|
|
82
|
+
|
|
83
|
+
Learn more at [maquina.app/documentation/ai-tools](https://maquina.app/documentation/ai-tools/).
|
|
84
|
+
|
|
85
|
+
## Learn More
|
|
86
|
+
|
|
87
|
+
Visit [maquina.app](https://maquina.app) for full documentation.
|
|
88
|
+
|
|
89
|
+
Maquina is built for the one-person framework philosophy: production-first, standard Rails, designed to scale with a small team.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// Entry point for the build script
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
|
|
2
|
+
<section class="bg-primary/5 border-b border-border">
|
|
3
|
+
<div class="max-w-5xl mx-auto px-5 py-20 sm:py-28">
|
|
4
|
+
<h1 class="text-4xl sm:text-5xl font-bold tracking-tight text-foreground mb-5">
|
|
5
|
+
Tools for Rails developers<br class="hidden sm:block"> who ship alone
|
|
6
|
+
</h1>
|
|
7
|
+
<p class="text-lg text-muted-foreground leading-relaxed max-w-2xl mb-8">
|
|
8
|
+
Maquina is a growing collection of open-source tools extracted from production Rails applications.
|
|
9
|
+
UI components, background jobs, error tracking, and authentication — configured and ready to go.
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
</div>
|
|
14
|
+
</section>
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
<section class="max-w-5xl mx-auto px-5 py-12">
|
|
20
|
+
<p class="text-sm font-semibold uppercase tracking-wider text-primary mb-6">What's Included</p>
|
|
21
|
+
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
<%= render "components/card" do %>
|
|
26
|
+
<%= render "components/card/header" do %>
|
|
27
|
+
<%= render "components/card/title", text: "Background Jobs" %>
|
|
28
|
+
<% end %>
|
|
29
|
+
<%= render "components/card/content" do %>
|
|
30
|
+
<p class="text-sm text-muted-foreground">Solid Queue backed by SQLite. Includes Mission Control dashboard for monitoring and managing jobs.</p>
|
|
31
|
+
<% end %>
|
|
32
|
+
<% end %>
|
|
33
|
+
|
|
34
|
+
<%= render "components/card" do %>
|
|
35
|
+
<%= render "components/card/header" do %>
|
|
36
|
+
<%= render "components/card/title", text: "Error Tracking" %>
|
|
37
|
+
<% end %>
|
|
38
|
+
<%= render "components/card/content" do %>
|
|
39
|
+
<p class="text-sm text-muted-foreground">Solid Errors captures exceptions automatically. Browse, resolve, and clean up — no external service needed.</p>
|
|
40
|
+
<% end %>
|
|
41
|
+
<% end %>
|
|
42
|
+
|
|
43
|
+
<%= render "components/card" do %>
|
|
44
|
+
<%= render "components/card/header" do %>
|
|
45
|
+
<%= render "components/card/title", text: "Rate Limiting" %>
|
|
46
|
+
<% end %>
|
|
47
|
+
<%= render "components/card/content" do %>
|
|
48
|
+
<p class="text-sm text-muted-foreground">Rack::Attack bans scanners and floods and throttles sign-in. Every refusal shows on the Security dashboard.</p>
|
|
49
|
+
<% end %>
|
|
50
|
+
<% end %>
|
|
51
|
+
|
|
52
|
+
<%= render "components/card" do %>
|
|
53
|
+
<%= render "components/card/header" do %>
|
|
54
|
+
<%= render "components/card/title", text: "Caching" %>
|
|
55
|
+
<% end %>
|
|
56
|
+
<%= render "components/card/content" do %>
|
|
57
|
+
<p class="text-sm text-muted-foreground">Solid Cache with SQLite backend. No Redis or Memcached to manage.</p>
|
|
58
|
+
<% end %>
|
|
59
|
+
<% end %>
|
|
60
|
+
|
|
61
|
+
<%= render "components/card" do %>
|
|
62
|
+
<%= render "components/card/header" do %>
|
|
63
|
+
<%= render "components/card/title", text: "Real-time" %>
|
|
64
|
+
<% end %>
|
|
65
|
+
<%= render "components/card/content" do %>
|
|
66
|
+
<p class="text-sm text-muted-foreground">Solid Cable for WebSocket support. Action Cable backed by SQLite — zero external dependencies.</p>
|
|
67
|
+
<% end %>
|
|
68
|
+
<% end %>
|
|
69
|
+
|
|
70
|
+
<%= render "components/card" do %>
|
|
71
|
+
<%= render "components/card/header" do %>
|
|
72
|
+
<%= render "components/card/title", text: "UI Components" %>
|
|
73
|
+
<% end %>
|
|
74
|
+
<%= render "components/card/content" do %>
|
|
75
|
+
<p class="text-sm text-muted-foreground">maquina_components — ERB partials styled with Tailwind CSS and Stimulus controllers. No React, no build step.</p>
|
|
76
|
+
<% end %>
|
|
77
|
+
<% end %>
|
|
78
|
+
|
|
79
|
+
<%= render "components/card" do %>
|
|
80
|
+
<%= render "components/card/header" do %>
|
|
81
|
+
<%= render "components/card/title", text: "Standard Rails" %>
|
|
82
|
+
<% end %>
|
|
83
|
+
<%= render "components/card/content" do %>
|
|
84
|
+
<p class="text-sm text-muted-foreground">Importmaps, Turbo, Stimulus. No webpack, no bundler, no extra frameworks to learn.</p>
|
|
85
|
+
<% end %>
|
|
86
|
+
<% end %>
|
|
87
|
+
|
|
88
|
+
</div>
|
|
89
|
+
</section>
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
<section class="max-w-5xl mx-auto px-5 pb-12">
|
|
93
|
+
<%= render "components/card" do %>
|
|
94
|
+
<%= render "components/card/header" do %>
|
|
95
|
+
<%= render "components/card/title", text: "Maquina Components" %>
|
|
96
|
+
<%= render "components/card/description", text: "UI components for Rails — ERB partials styled with Tailwind CSS 4.0 and Stimulus controllers. Inspired by shadcn/ui, built for the Rails way." %>
|
|
97
|
+
<% end %>
|
|
98
|
+
<%= render "components/card/content" do %>
|
|
99
|
+
<div class="flex flex-wrap gap-2">
|
|
100
|
+
<%= render "components/badge", variant: :outline, size: :sm do %>Card<% end %>
|
|
101
|
+
<%= render "components/badge", variant: :outline, size: :sm do %>Badge<% end %>
|
|
102
|
+
<%= render "components/badge", variant: :outline, size: :sm do %>Table<% end %>
|
|
103
|
+
<%= render "components/badge", variant: :outline, size: :sm do %>Sidebar<% end %>
|
|
104
|
+
<%= render "components/badge", variant: :outline, size: :sm do %>Calendar<% end %>
|
|
105
|
+
<%= render "components/badge", variant: :outline, size: :sm do %>Combobox<% end %>
|
|
106
|
+
<%= render "components/badge", variant: :outline, size: :sm do %>Date Picker<% end %>
|
|
107
|
+
<%= render "components/badge", variant: :outline, size: :sm do %>Toast<% end %>
|
|
108
|
+
<%= render "components/badge", variant: :outline, size: :sm do %>Dropdown Menu<% end %>
|
|
109
|
+
<%= render "components/badge", variant: :outline, size: :sm do %>Toggle Group<% end %>
|
|
110
|
+
<%= render "components/badge", variant: :outline, size: :sm do %>Pagination<% end %>
|
|
111
|
+
<%= render "components/badge", variant: :outline, size: :sm do %>Breadcrumbs<% end %>
|
|
112
|
+
<%= render "components/badge", variant: :outline, size: :sm do %>Alert<% end %>
|
|
113
|
+
<%= render "components/badge", variant: :outline, size: :sm do %>Empty State<% end %>
|
|
114
|
+
<%= render "components/badge", variant: :outline, size: :sm do %>Forms<% end %>
|
|
115
|
+
</div>
|
|
116
|
+
<% end %>
|
|
117
|
+
<%= render "components/card/footer" do %>
|
|
118
|
+
<%= link_to "Browse Components", "https://maquina.app/documentation/components/", target: "_blank", rel: "noopener noreferrer", data: { component: "button", variant: "primary" } %>
|
|
119
|
+
<% end %>
|
|
120
|
+
<% end %>
|
|
121
|
+
</section>
|
|
122
|
+
|
|
123
|
+
<div class="max-w-5xl mx-auto px-5">
|
|
124
|
+
<%= render "components/separator" %>
|
|
125
|
+
</div>
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
<section class="max-w-5xl mx-auto px-5 py-12">
|
|
129
|
+
<p class="text-sm font-semibold uppercase tracking-wider text-primary mb-6">Ecosystem</p>
|
|
130
|
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
131
|
+
|
|
132
|
+
<%= render "components/card" do %>
|
|
133
|
+
<%= render "components/card/header" do %>
|
|
134
|
+
<%= render "components/card/title", text: "Rails MCP Server" %>
|
|
135
|
+
<% end %>
|
|
136
|
+
<%= render "components/card/content" do %>
|
|
137
|
+
<p class="text-sm text-muted-foreground">A Model Context Protocol server for Rails projects. Analyze models, routes, schemas, and execute read-only Ruby code in your Rails context.</p>
|
|
138
|
+
<% end %>
|
|
139
|
+
<% end %>
|
|
140
|
+
|
|
141
|
+
<%= render "components/card" do %>
|
|
142
|
+
<%= render "components/card/header" do %>
|
|
143
|
+
<%= render "components/card/title", text: "Neovim MCP Server" %>
|
|
144
|
+
<% end %>
|
|
145
|
+
<%= render "components/card/content" do %>
|
|
146
|
+
<p class="text-sm text-muted-foreground">MCP server for Neovim integration. Read and update buffers, coordinate file changes across your editor and AI assistants.</p>
|
|
147
|
+
<% end %>
|
|
148
|
+
<% end %>
|
|
149
|
+
|
|
150
|
+
<%= render "components/card" do %>
|
|
151
|
+
<%= render "components/card/header" do %>
|
|
152
|
+
<%= render "components/card/title", text: "Rails Upgrade Assistant" %>
|
|
153
|
+
<% end %>
|
|
154
|
+
<%= render "components/card/content" do %>
|
|
155
|
+
<p class="text-sm text-muted-foreground">A Claude Skill that analyzes Rails applications and generates upgrade guides. Covers Rails 7.0 through 8.1 with breaking changes and migration steps.</p>
|
|
156
|
+
<% end %>
|
|
157
|
+
<% end %>
|
|
158
|
+
|
|
159
|
+
<%= render "components/card" do %>
|
|
160
|
+
<%= render "components/card/header" do %>
|
|
161
|
+
<%= render "components/card/title", text: "Rails Simplifier" %>
|
|
162
|
+
<% end %>
|
|
163
|
+
<%= render "components/card/content" do %>
|
|
164
|
+
<p class="text-sm text-muted-foreground">Code simplification following 37signals patterns and the One Person Framework philosophy.</p>
|
|
165
|
+
<% end %>
|
|
166
|
+
<% end %>
|
|
167
|
+
|
|
168
|
+
</div>
|
|
169
|
+
<div class="mt-6 text-center">
|
|
170
|
+
<%= link_to "Explore All Tools", "https://maquina.app/", target: "_blank", rel: "noopener noreferrer", data: { component: "button", variant: "outline" } %>
|
|
171
|
+
</div>
|
|
172
|
+
</section>
|
|
173
|
+
|
|
174
|
+
<div class="max-w-5xl mx-auto px-5">
|
|
175
|
+
<%= render "components/separator" %>
|
|
176
|
+
</div>
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
<section class="max-w-5xl mx-auto px-5 py-12">
|
|
180
|
+
<p class="text-sm font-semibold uppercase tracking-wider text-primary mb-8 text-center">Philosophy</p>
|
|
181
|
+
<div class="grid grid-cols-1 sm:grid-cols-3 gap-10">
|
|
182
|
+
<div>
|
|
183
|
+
<h3 class="font-bold text-lg text-foreground mb-2">Production First</h3>
|
|
184
|
+
<p class="text-sm text-muted-foreground leading-relaxed">Every tool starts in a real application. No theoretical exercises — only code that has shipped.</p>
|
|
185
|
+
</div>
|
|
186
|
+
<div>
|
|
187
|
+
<h3 class="font-bold text-lg text-foreground mb-2">Standard Rails</h3>
|
|
188
|
+
<p class="text-sm text-muted-foreground leading-relaxed">ERB, Tailwind, Stimulus. No new paradigms to learn, no complex build pipelines.</p>
|
|
189
|
+
</div>
|
|
190
|
+
<div>
|
|
191
|
+
<h3 class="font-bold text-lg text-foreground mb-2">One Person Scale</h3>
|
|
192
|
+
<p class="text-sm text-muted-foreground leading-relaxed">Built for developers who ship alone. Simple tools that stay out of your way.</p>
|
|
193
|
+
</div>
|
|
194
|
+
</div>
|
|
195
|
+
</section>
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
<section class="bg-primary/5 border-t border-border">
|
|
199
|
+
<div class="max-w-5xl mx-auto px-5 py-16 text-center">
|
|
200
|
+
<h2 class="text-2xl font-bold text-foreground mb-4">Start building today</h2>
|
|
201
|
+
<p class="text-muted-foreground mb-6">Visit maquina.app to explore the full ecosystem.</p>
|
|
202
|
+
<%= link_to "Visit maquina.app", "https://maquina.app/", target: "_blank", rel: "noopener noreferrer", data: { component: "button", variant: "primary" } %>
|
|
203
|
+
</div>
|
|
204
|
+
</section>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require_relative "boot"
|
|
2
|
+
require "rails/all"
|
|
3
|
+
|
|
4
|
+
module TestApp
|
|
5
|
+
class Application < Rails::Application
|
|
6
|
+
|
|
7
|
+
# Use Solid Queue as the Active Job backend in all environments except test
|
|
8
|
+
config.active_job.queue_adapter = :solid_queue unless Rails.env.test?
|
|
9
|
+
config.solid_queue.connects_to = {database: {writing: :queue}}
|
|
10
|
+
|
|
11
|
+
# Don't wrap form fields with errors in an extra div
|
|
12
|
+
config.action_view.field_error_proc = proc { |html_tag, _instance| html_tag }
|
|
13
|
+
config.load_defaults 7.2
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# SQLite. Versions 3.8.0 and up are supported.
|
|
2
|
+
# gem install sqlite3
|
|
3
|
+
#
|
|
4
|
+
# Ensure the SQLite 3 gem is defined in your Gemfile
|
|
5
|
+
# gem "sqlite3"
|
|
6
|
+
#
|
|
7
|
+
default: &default
|
|
8
|
+
adapter: sqlite3
|
|
9
|
+
max_connections: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
|
|
10
|
+
timeout: 5000
|
|
11
|
+
|
|
12
|
+
development:
|
|
13
|
+
primary:
|
|
14
|
+
<<: *default
|
|
15
|
+
database: storage/development.sqlite3
|
|
16
|
+
queue:
|
|
17
|
+
<<: *default
|
|
18
|
+
database: storage/development_queue.sqlite3
|
|
19
|
+
migrations_paths: db/queue_migrate
|
|
20
|
+
cache:
|
|
21
|
+
<<: *default
|
|
22
|
+
database: storage/development_cache.sqlite3
|
|
23
|
+
migrations_paths: db/cache_migrate
|
|
24
|
+
cable:
|
|
25
|
+
<<: *default
|
|
26
|
+
database: storage/development_cable.sqlite3
|
|
27
|
+
migrations_paths: db/cable_migrate
|
|
28
|
+
errors:
|
|
29
|
+
<<: *default
|
|
30
|
+
database: storage/development_errors.sqlite3
|
|
31
|
+
migrations_paths: db/errors_migrate
|
|
32
|
+
security:
|
|
33
|
+
<<: *default
|
|
34
|
+
database: storage/development_security.sqlite3
|
|
35
|
+
migrations_paths: db/security_migrate
|
|
36
|
+
|
|
37
|
+
# Warning: The database defined as "test" will be erased and
|
|
38
|
+
# re-generated from your development database when you run "rake".
|
|
39
|
+
# Do not set this db to the same as development or production.
|
|
40
|
+
test:
|
|
41
|
+
primary:
|
|
42
|
+
<<: *default
|
|
43
|
+
database: storage/test.sqlite3
|
|
44
|
+
queue:
|
|
45
|
+
<<: *default
|
|
46
|
+
database: storage/test_queue.sqlite3
|
|
47
|
+
migrations_paths: db/queue_migrate
|
|
48
|
+
cache:
|
|
49
|
+
<<: *default
|
|
50
|
+
database: storage/test_cache.sqlite3
|
|
51
|
+
migrations_paths: db/cache_migrate
|
|
52
|
+
cable:
|
|
53
|
+
<<: *default
|
|
54
|
+
database: storage/test_cable.sqlite3
|
|
55
|
+
migrations_paths: db/cable_migrate
|
|
56
|
+
errors:
|
|
57
|
+
<<: *default
|
|
58
|
+
database: storage/test_errors.sqlite3
|
|
59
|
+
migrations_paths: db/errors_migrate
|
|
60
|
+
security:
|
|
61
|
+
<<: *default
|
|
62
|
+
database: storage/test_security.sqlite3
|
|
63
|
+
migrations_paths: db/security_migrate
|
|
64
|
+
|
|
65
|
+
# Store production database in the storage/ directory, which by default
|
|
66
|
+
# is mounted as a persistent Docker volume in config/deploy.yml.
|
|
67
|
+
production:
|
|
68
|
+
primary:
|
|
69
|
+
<<: *default
|
|
70
|
+
database: storage/production.sqlite3
|
|
71
|
+
queue:
|
|
72
|
+
<<: *default
|
|
73
|
+
database: storage/production_queue.sqlite3
|
|
74
|
+
migrations_paths: db/queue_migrate
|
|
75
|
+
cache:
|
|
76
|
+
<<: *default
|
|
77
|
+
database: storage/production_cache.sqlite3
|
|
78
|
+
migrations_paths: db/cache_migrate
|
|
79
|
+
cable:
|
|
80
|
+
<<: *default
|
|
81
|
+
database: storage/production_cable.sqlite3
|
|
82
|
+
migrations_paths: db/cable_migrate
|
|
83
|
+
errors:
|
|
84
|
+
<<: *default
|
|
85
|
+
database: storage/production_errors.sqlite3
|
|
86
|
+
migrations_paths: db/errors_migrate
|
|
87
|
+
security:
|
|
88
|
+
<<: *default
|
|
89
|
+
database: storage/production_security.sqlite3
|
|
90
|
+
migrations_paths: db/security_migrate
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# SQLite. Versions 3.8.0 and up are supported.
|
|
2
|
+
# gem install sqlite3
|
|
3
|
+
#
|
|
4
|
+
# Ensure the SQLite 3 gem is defined in your Gemfile
|
|
5
|
+
# gem "sqlite3"
|
|
6
|
+
#
|
|
7
|
+
default: &default
|
|
8
|
+
adapter: sqlite3
|
|
9
|
+
max_connections: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
|
|
10
|
+
timeout: 5000
|
|
11
|
+
|
|
12
|
+
development:
|
|
13
|
+
primary:
|
|
14
|
+
<<: *default
|
|
15
|
+
database: storage/development.sqlite3
|
|
16
|
+
queue:
|
|
17
|
+
<<: *default
|
|
18
|
+
database: storage/development_queue.sqlite3
|
|
19
|
+
migrations_paths: db/queue_migrate
|
|
20
|
+
cache:
|
|
21
|
+
<<: *default
|
|
22
|
+
database: storage/development_cache.sqlite3
|
|
23
|
+
migrations_paths: db/cache_migrate
|
|
24
|
+
cable:
|
|
25
|
+
<<: *default
|
|
26
|
+
database: storage/development_cable.sqlite3
|
|
27
|
+
migrations_paths: db/cable_migrate
|
|
28
|
+
errors:
|
|
29
|
+
<<: *default
|
|
30
|
+
database: storage/development_errors.sqlite3
|
|
31
|
+
migrations_paths: db/errors_migrate
|
|
32
|
+
security:
|
|
33
|
+
<<: *default
|
|
34
|
+
database: storage/development_security.sqlite3
|
|
35
|
+
migrations_paths: db/security_migrate
|
|
36
|
+
|
|
37
|
+
# Warning: The database defined as "test" will be erased and
|
|
38
|
+
# re-generated from your development database when you run "rake".
|
|
39
|
+
# Do not set this db to the same as development or production.
|
|
40
|
+
test:
|
|
41
|
+
primary:
|
|
42
|
+
<<: *default
|
|
43
|
+
database: storage/test.sqlite3
|
|
44
|
+
queue:
|
|
45
|
+
<<: *default
|
|
46
|
+
database: storage/test_queue.sqlite3
|
|
47
|
+
migrations_paths: db/queue_migrate
|
|
48
|
+
cache:
|
|
49
|
+
<<: *default
|
|
50
|
+
database: storage/test_cache.sqlite3
|
|
51
|
+
migrations_paths: db/cache_migrate
|
|
52
|
+
cable:
|
|
53
|
+
<<: *default
|
|
54
|
+
database: storage/test_cable.sqlite3
|
|
55
|
+
migrations_paths: db/cable_migrate
|
|
56
|
+
errors:
|
|
57
|
+
<<: *default
|
|
58
|
+
database: storage/test_errors.sqlite3
|
|
59
|
+
migrations_paths: db/errors_migrate
|
|
60
|
+
security:
|
|
61
|
+
<<: *default
|
|
62
|
+
database: storage/test_security.sqlite3
|
|
63
|
+
migrations_paths: db/security_migrate
|
|
64
|
+
|
|
65
|
+
# Store production database in the storage/ directory, which by default
|
|
66
|
+
# is mounted as a persistent Docker volume in config/deploy.yml.
|
|
67
|
+
production:
|
|
68
|
+
primary:
|
|
69
|
+
<<: *default
|
|
70
|
+
database: storage/production.sqlite3
|
|
71
|
+
queue:
|
|
72
|
+
<<: *default
|
|
73
|
+
database: storage/production_queue.sqlite3
|
|
74
|
+
migrations_paths: db/queue_migrate
|
|
75
|
+
cache:
|
|
76
|
+
<<: *default
|
|
77
|
+
database: storage/production_cache.sqlite3
|
|
78
|
+
migrations_paths: db/cache_migrate
|
|
79
|
+
cable:
|
|
80
|
+
<<: *default
|
|
81
|
+
database: storage/production_cable.sqlite3
|
|
82
|
+
migrations_paths: db/cable_migrate
|
|
83
|
+
errors:
|
|
84
|
+
<<: *default
|
|
85
|
+
database: storage/production_errors.sqlite3
|
|
86
|
+
migrations_paths: db/errors_migrate
|
|
87
|
+
security:
|
|
88
|
+
<<: *default
|
|
89
|
+
database: storage/production_security.sqlite3
|
|
90
|
+
migrations_paths: db/security_migrate
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Rails.application.configure do
|
|
2
|
+
config.cache_classes = false
|
|
3
|
+
|
|
4
|
+
# Use letter_opener for email delivery
|
|
5
|
+
config.action_mailer.delivery_method = :letter_opener
|
|
6
|
+
config.action_mailer.perform_deliveries = true
|
|
7
|
+
config.action_mailer.default_url_options = {host: "localhost", port: 3000}
|
|
8
|
+
end
|