pg_sql_triggers 1.0.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/.rspec +3 -0
- data/.rubocop.yml +120 -0
- data/CHANGELOG.md +52 -0
- data/Goal.md +294 -0
- data/LICENSE +21 -0
- data/README.md +294 -0
- data/RELEASE.md +270 -0
- data/Rakefile +16 -0
- data/app/assets/javascripts/pg_sql_triggers/application.js +5 -0
- data/app/assets/stylesheets/pg_sql_triggers/application.css +179 -0
- data/app/controllers/pg_sql_triggers/application_controller.rb +35 -0
- data/app/controllers/pg_sql_triggers/dashboard_controller.rb +42 -0
- data/app/controllers/pg_sql_triggers/generator_controller.rb +145 -0
- data/app/controllers/pg_sql_triggers/migrations_controller.rb +84 -0
- data/app/controllers/pg_sql_triggers/tables_controller.rb +44 -0
- data/app/models/pg_sql_triggers/application_record.rb +7 -0
- data/app/models/pg_sql_triggers/trigger_registry.rb +93 -0
- data/app/views/layouts/pg_sql_triggers/application.html.erb +72 -0
- data/app/views/pg_sql_triggers/dashboard/index.html.erb +225 -0
- data/app/views/pg_sql_triggers/generator/new.html.erb +370 -0
- data/app/views/pg_sql_triggers/generator/preview.html.erb +77 -0
- data/app/views/pg_sql_triggers/tables/index.html.erb +105 -0
- data/app/views/pg_sql_triggers/tables/show.html.erb +126 -0
- data/config/routes.rb +35 -0
- data/db/migrate/20251222000001_create_pg_sql_triggers_tables.rb +29 -0
- data/lib/generators/pg_sql_triggers/install_generator.rb +36 -0
- data/lib/generators/pg_sql_triggers/templates/README +36 -0
- data/lib/generators/pg_sql_triggers/templates/create_pg_sql_triggers_tables.rb +36 -0
- data/lib/generators/pg_sql_triggers/templates/initializer.rb +27 -0
- data/lib/generators/pg_sql_triggers/templates/trigger_migration.rb.erb +32 -0
- data/lib/generators/pg_sql_triggers/trigger_migration_generator.rb +60 -0
- data/lib/generators/trigger/migration_generator.rb +60 -0
- data/lib/pg_sql_triggers/database_introspection.rb +251 -0
- data/lib/pg_sql_triggers/drift.rb +24 -0
- data/lib/pg_sql_triggers/dsl/trigger_definition.rb +67 -0
- data/lib/pg_sql_triggers/dsl.rb +15 -0
- data/lib/pg_sql_triggers/engine.rb +29 -0
- data/lib/pg_sql_triggers/generator/form.rb +78 -0
- data/lib/pg_sql_triggers/generator/service.rb +251 -0
- data/lib/pg_sql_triggers/generator.rb +8 -0
- data/lib/pg_sql_triggers/migration.rb +15 -0
- data/lib/pg_sql_triggers/migrator.rb +237 -0
- data/lib/pg_sql_triggers/permissions/checker.rb +33 -0
- data/lib/pg_sql_triggers/permissions.rb +35 -0
- data/lib/pg_sql_triggers/registry/manager.rb +47 -0
- data/lib/pg_sql_triggers/registry/validator.rb +15 -0
- data/lib/pg_sql_triggers/registry.rb +36 -0
- data/lib/pg_sql_triggers/sql.rb +21 -0
- data/lib/pg_sql_triggers/testing/dry_run.rb +74 -0
- data/lib/pg_sql_triggers/testing/function_tester.rb +118 -0
- data/lib/pg_sql_triggers/testing/safe_executor.rb +66 -0
- data/lib/pg_sql_triggers/testing/syntax_validator.rb +124 -0
- data/lib/pg_sql_triggers/testing.rb +10 -0
- data/lib/pg_sql_triggers/version.rb +15 -0
- data/lib/pg_sql_triggers.rb +41 -0
- data/lib/tasks/trigger_migrations.rake +254 -0
- data/sig/pg_sql_triggers.rbs +4 -0
- metadata +260 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 868dfd4da507455302b3e00e6dd27a8cc5440c6e81c60e978e10a031a339e8c1
|
|
4
|
+
data.tar.gz: e8b013e8485431fac4d30bfd7f3faade2130b4b55d1be4cfbf0f9ffdbad2ef6f
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 1265add39a041703438f7406a6a4b9c6f7b6e5dcf06240c8dc53c53f97c747cea850f1fa603d9eacbe072a43fbc4fe0cc371536e2bd8a215f30609171ccb8ffa
|
|
7
|
+
data.tar.gz: e0d649df16316ef840fd5d42ef199b5dcf9f22d4ebe20134250ffe8b369d52c16f3774640ab95294ca487f4cb065d624bb7e386d1c223de536fc3dfc16d03511
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
require:
|
|
2
|
+
- rubocop-rspec
|
|
3
|
+
- rubocop-rspec_rails
|
|
4
|
+
|
|
5
|
+
plugins:
|
|
6
|
+
- rubocop-rails
|
|
7
|
+
- rubocop-capybara
|
|
8
|
+
- rubocop-factory_bot
|
|
9
|
+
|
|
10
|
+
AllCops:
|
|
11
|
+
TargetRubyVersion: 2.7
|
|
12
|
+
NewCops: enable
|
|
13
|
+
SuggestExtensions: false
|
|
14
|
+
Exclude:
|
|
15
|
+
- 'bin/**/*'
|
|
16
|
+
- 'vendor/**/*'
|
|
17
|
+
- 'node_modules/**/*'
|
|
18
|
+
- 'db/schema.rb'
|
|
19
|
+
- 'tmp/**/*'
|
|
20
|
+
- 'spec/dummy/**/*'
|
|
21
|
+
|
|
22
|
+
# Metrics
|
|
23
|
+
Metrics/AbcSize:
|
|
24
|
+
Max: 65
|
|
25
|
+
Exclude:
|
|
26
|
+
- 'spec/**/*'
|
|
27
|
+
- 'app/controllers/**/*'
|
|
28
|
+
- 'lib/generators/**/*'
|
|
29
|
+
- 'lib/pg_sql_triggers/testing/**/*'
|
|
30
|
+
|
|
31
|
+
Metrics/BlockLength:
|
|
32
|
+
Max: 50
|
|
33
|
+
Exclude:
|
|
34
|
+
- 'spec/**/*'
|
|
35
|
+
- 'config/routes.rb'
|
|
36
|
+
- '*.gemspec'
|
|
37
|
+
- 'lib/tasks/**/*'
|
|
38
|
+
|
|
39
|
+
Metrics/ClassLength:
|
|
40
|
+
Max: 200
|
|
41
|
+
Exclude:
|
|
42
|
+
- 'spec/**/*'
|
|
43
|
+
|
|
44
|
+
Metrics/CyclomaticComplexity:
|
|
45
|
+
Max: 18
|
|
46
|
+
Exclude:
|
|
47
|
+
- 'app/controllers/**/*'
|
|
48
|
+
- 'lib/pg_sql_triggers/testing/**/*'
|
|
49
|
+
|
|
50
|
+
Metrics/MethodLength:
|
|
51
|
+
Max: 55
|
|
52
|
+
Exclude:
|
|
53
|
+
- 'spec/**/*'
|
|
54
|
+
- 'app/controllers/**/*'
|
|
55
|
+
- 'lib/generators/**/*'
|
|
56
|
+
- 'lib/pg_sql_triggers/testing/**/*'
|
|
57
|
+
|
|
58
|
+
Metrics/PerceivedComplexity:
|
|
59
|
+
Max: 15
|
|
60
|
+
Exclude:
|
|
61
|
+
- 'app/controllers/**/*'
|
|
62
|
+
- 'lib/pg_sql_triggers/testing/**/*'
|
|
63
|
+
|
|
64
|
+
# Style
|
|
65
|
+
Style/Documentation:
|
|
66
|
+
Enabled: false
|
|
67
|
+
|
|
68
|
+
Style/StringLiterals:
|
|
69
|
+
EnforcedStyle: double_quotes
|
|
70
|
+
|
|
71
|
+
Style/FrozenStringLiteralComment:
|
|
72
|
+
Enabled: true
|
|
73
|
+
|
|
74
|
+
# Layout
|
|
75
|
+
Layout/LineLength:
|
|
76
|
+
Max: 120
|
|
77
|
+
Exclude:
|
|
78
|
+
- 'spec/**/*'
|
|
79
|
+
|
|
80
|
+
# Gemspec
|
|
81
|
+
Gemspec/DevelopmentDependencies:
|
|
82
|
+
Enabled: false
|
|
83
|
+
|
|
84
|
+
# Rails
|
|
85
|
+
Rails:
|
|
86
|
+
Enabled: true
|
|
87
|
+
|
|
88
|
+
Rails/I18nLocaleTexts:
|
|
89
|
+
Enabled: false
|
|
90
|
+
|
|
91
|
+
# RSpec
|
|
92
|
+
RSpec/ExampleLength:
|
|
93
|
+
Max: 10
|
|
94
|
+
Exclude:
|
|
95
|
+
- 'spec/**/*_spec.rb'
|
|
96
|
+
|
|
97
|
+
RSpec/FilePath:
|
|
98
|
+
Enabled: false
|
|
99
|
+
|
|
100
|
+
RSpec/InstanceVariable:
|
|
101
|
+
Enabled: false
|
|
102
|
+
|
|
103
|
+
RSpec/MessageChain:
|
|
104
|
+
Enabled: false
|
|
105
|
+
|
|
106
|
+
RSpec/MessageSpies:
|
|
107
|
+
Enabled: false
|
|
108
|
+
|
|
109
|
+
RSpec/MultipleDescribes:
|
|
110
|
+
Enabled: false
|
|
111
|
+
|
|
112
|
+
RSpec/MultipleExpectations:
|
|
113
|
+
Max: 10
|
|
114
|
+
|
|
115
|
+
RSpec/SpecFilePathFormat:
|
|
116
|
+
Enabled: false
|
|
117
|
+
|
|
118
|
+
# Capybara
|
|
119
|
+
Capybara/RSpec/PredicateMatcher:
|
|
120
|
+
Enabled: false
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.0.0] - 2025-12-27
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Initial gem structure
|
|
12
|
+
- PostgreSQL trigger DSL for defining triggers with version and environment support
|
|
13
|
+
- Trigger registry system for tracking trigger metadata (trigger_name, table_name, version, enabled, checksum, source, environment)
|
|
14
|
+
- Drift detection between DSL definitions and database state (Managed & In Sync, Managed & Drifted, Manual Override, Disabled, Dropped, Unknown)
|
|
15
|
+
- Permission system with three levels (Viewer, Operator, Admin)
|
|
16
|
+
- Mountable Rails Engine with web UI for trigger management
|
|
17
|
+
- Production kill switch for safety (blocks destructive operations in production by default)
|
|
18
|
+
- Console introspection APIs (list, enabled, disabled, for_table, diff, validate!)
|
|
19
|
+
- Migration system for registry table
|
|
20
|
+
- Install generator (`rails generate pg_sql_triggers:install`)
|
|
21
|
+
- Trigger migration system similar to Rails schema migrations
|
|
22
|
+
- Generate trigger migrations
|
|
23
|
+
- Run pending migrations (`rake trigger:migrate`)
|
|
24
|
+
- Rollback migrations (`rake trigger:rollback`)
|
|
25
|
+
- Migration status and individual migration controls
|
|
26
|
+
- Combined schema and trigger migration tasks (`rake db:migrate:with_triggers`)
|
|
27
|
+
- Web UI for trigger migrations (up/down/redo)
|
|
28
|
+
- Apply all pending migrations from dashboard
|
|
29
|
+
- Rollback last migration
|
|
30
|
+
- Redo last migration
|
|
31
|
+
- Individual migration actions (up/down/redo) for each migration
|
|
32
|
+
- Flash messages for success, error, warning, and info states
|
|
33
|
+
- Database introspection for trigger state detection
|
|
34
|
+
- SQL execution support with safety checks
|
|
35
|
+
- Trigger generator with form and service layer
|
|
36
|
+
- Testing utilities for safe execution and syntax validation
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
- Initial release
|
|
40
|
+
|
|
41
|
+
### Deprecated
|
|
42
|
+
- Nothing yet
|
|
43
|
+
|
|
44
|
+
### Removed
|
|
45
|
+
- Nothing yet
|
|
46
|
+
|
|
47
|
+
### Fixed
|
|
48
|
+
- Initial release
|
|
49
|
+
|
|
50
|
+
### Security
|
|
51
|
+
- Production kill switch prevents destructive operations in production environments
|
|
52
|
+
- Permission system enforces role-based access control (Viewer, Operator, Admin)
|
data/Goal.md
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
You are building a **production-grade Ruby on Rails gem** named **pg_sql_triggers**.
|
|
2
|
+
|
|
3
|
+
This gem is **not a toy generator**.
|
|
4
|
+
It is a **PostgreSQL Trigger Control Plane for Rails**, designed for real teams running production systems.
|
|
5
|
+
|
|
6
|
+
You must follow everything below strictly.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 1. Problem Statement
|
|
11
|
+
|
|
12
|
+
Rails teams use PostgreSQL triggers for:
|
|
13
|
+
- data integrity
|
|
14
|
+
- performance
|
|
15
|
+
- billing logic
|
|
16
|
+
|
|
17
|
+
But triggers today are:
|
|
18
|
+
- managed manually
|
|
19
|
+
- invisible to Rails
|
|
20
|
+
- unsafe to deploy
|
|
21
|
+
- easy to drift
|
|
22
|
+
|
|
23
|
+
This gem brings triggers into the Rails ecosystem with:
|
|
24
|
+
- lifecycle management
|
|
25
|
+
- safe deploys
|
|
26
|
+
- versioning
|
|
27
|
+
- UI control
|
|
28
|
+
- emergency SQL escape hatches
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 2. Core Philosophy
|
|
33
|
+
|
|
34
|
+
- Rails-native
|
|
35
|
+
- Explicit over magic
|
|
36
|
+
- Safe by default
|
|
37
|
+
- Power with guardrails
|
|
38
|
+
|
|
39
|
+
This gem **manages lifecycle**, not business logic.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 3. Supported Capabilities (MUST IMPLEMENT)
|
|
44
|
+
|
|
45
|
+
### A. Trigger Declaration (DSL)
|
|
46
|
+
|
|
47
|
+
Developers declare triggers using Ruby DSL:
|
|
48
|
+
|
|
49
|
+
```ruby
|
|
50
|
+
pg_sql_trigger "users_email_validation" do
|
|
51
|
+
table :users
|
|
52
|
+
on :insert, :update
|
|
53
|
+
function :validate_user_email
|
|
54
|
+
|
|
55
|
+
version 3
|
|
56
|
+
enabled true
|
|
57
|
+
|
|
58
|
+
when_env :production
|
|
59
|
+
end
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Rules:
|
|
63
|
+
- DSL generates metadata, NOT raw SQL
|
|
64
|
+
- Every trigger has a version
|
|
65
|
+
- Triggers are environment-aware
|
|
66
|
+
- Triggers can be enabled or disabled
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
### B. Trigger Generation
|
|
71
|
+
|
|
72
|
+
The gem must generate triggers safely.
|
|
73
|
+
|
|
74
|
+
Generators create:
|
|
75
|
+
1. Trigger DSL file
|
|
76
|
+
2. Function stub (PL/pgSQL)
|
|
77
|
+
3. Manifest metadata
|
|
78
|
+
|
|
79
|
+
Rules:
|
|
80
|
+
- Generated triggers are **disabled by default**
|
|
81
|
+
- Nothing executes automatically
|
|
82
|
+
- Developers must explicitly apply
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
### C. Trigger Registry (Source of Truth)
|
|
87
|
+
|
|
88
|
+
All triggers must be tracked in a registry table.
|
|
89
|
+
|
|
90
|
+
Registry tracks:
|
|
91
|
+
- trigger_name
|
|
92
|
+
- table_name
|
|
93
|
+
- version
|
|
94
|
+
- enabled
|
|
95
|
+
- checksum
|
|
96
|
+
- source (dsl / generated / manual_sql)
|
|
97
|
+
- environment
|
|
98
|
+
- installed_at
|
|
99
|
+
- last_verified_at
|
|
100
|
+
|
|
101
|
+
Rails must always know:
|
|
102
|
+
- what exists
|
|
103
|
+
- how it was created
|
|
104
|
+
- whether it drifted
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
### D. Safe Apply & Deploy
|
|
109
|
+
|
|
110
|
+
Applying triggers must:
|
|
111
|
+
- Run in a transaction
|
|
112
|
+
- Diff expected vs actual
|
|
113
|
+
- Never blindly DROP + CREATE
|
|
114
|
+
- Support rollback on failure
|
|
115
|
+
- Update registry atomically
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
### E. Drift Detection
|
|
120
|
+
|
|
121
|
+
System must detect:
|
|
122
|
+
- Missing triggers
|
|
123
|
+
- Version mismatch
|
|
124
|
+
- Function body drift
|
|
125
|
+
- Manual SQL overrides
|
|
126
|
+
- Unknown external triggers
|
|
127
|
+
|
|
128
|
+
Drift states:
|
|
129
|
+
1. Managed & In Sync
|
|
130
|
+
2. Managed & Drifted
|
|
131
|
+
3. Manual Override
|
|
132
|
+
4. Disabled
|
|
133
|
+
5. Dropped (Recorded)
|
|
134
|
+
6. Unknown (External)
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
### F. Rails Console Introspection
|
|
139
|
+
|
|
140
|
+
Provide console APIs:
|
|
141
|
+
|
|
142
|
+
PgSqlTrigger.list
|
|
143
|
+
PgSqlTrigger.enabled
|
|
144
|
+
PgSqlTrigger.disabled
|
|
145
|
+
PgSqlTrigger.for_table(:users)
|
|
146
|
+
PgSqlTrigger.diff
|
|
147
|
+
PgSqlTrigger.validate!
|
|
148
|
+
|
|
149
|
+
No raw SQL required by users.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## 4. Free-Form SQL Execution (MANDATORY)
|
|
154
|
+
|
|
155
|
+
The gem MUST support free-form SQL execution.
|
|
156
|
+
|
|
157
|
+
This is required for:
|
|
158
|
+
- emergency fixes
|
|
159
|
+
- complex migrations
|
|
160
|
+
- DB-owner workflows
|
|
161
|
+
|
|
162
|
+
### SQL Capsules
|
|
163
|
+
|
|
164
|
+
Free-form SQL is wrapped in **named SQL capsules**:
|
|
165
|
+
|
|
166
|
+
- Must be named
|
|
167
|
+
- Must declare environment
|
|
168
|
+
- Must declare purpose
|
|
169
|
+
- Must be applied explicitly
|
|
170
|
+
|
|
171
|
+
Rules:
|
|
172
|
+
- Runs in a transaction
|
|
173
|
+
- Checksum verified
|
|
174
|
+
- Registry updated
|
|
175
|
+
- Marked as `source = manual_sql`
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## 5. Permissions Model v1
|
|
180
|
+
|
|
181
|
+
Three permission levels:
|
|
182
|
+
|
|
183
|
+
### Viewer
|
|
184
|
+
- Read-only
|
|
185
|
+
- View triggers
|
|
186
|
+
- View diffs
|
|
187
|
+
|
|
188
|
+
### Operator
|
|
189
|
+
- Enable / Disable triggers
|
|
190
|
+
- Apply generated triggers
|
|
191
|
+
- Re-execute triggers in non-prod
|
|
192
|
+
- Dry-run SQL
|
|
193
|
+
|
|
194
|
+
### Admin
|
|
195
|
+
- Drop triggers
|
|
196
|
+
- Execute free-form SQL
|
|
197
|
+
- Re-execute triggers in any env
|
|
198
|
+
- Override drift
|
|
199
|
+
|
|
200
|
+
Permissions enforced in:
|
|
201
|
+
- UI
|
|
202
|
+
- CLI
|
|
203
|
+
- Console
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## 6. Kill Switch for Production SQL (MANDATORY)
|
|
208
|
+
|
|
209
|
+
Production mutations must be gated.
|
|
210
|
+
|
|
211
|
+
### Levels:
|
|
212
|
+
1. Global disable (default)
|
|
213
|
+
2. Runtime ENV override
|
|
214
|
+
3. Explicit confirmation text
|
|
215
|
+
4. Optional time-window auto-lock
|
|
216
|
+
|
|
217
|
+
Kill switch must:
|
|
218
|
+
- Block UI
|
|
219
|
+
- Block CLI
|
|
220
|
+
- Block console
|
|
221
|
+
- Always log attempts
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## 8. UI (Mountable Rails Engine)
|
|
226
|
+
|
|
227
|
+
UI is operational, not decorative.
|
|
228
|
+
|
|
229
|
+
### Dashboard
|
|
230
|
+
- Trigger name
|
|
231
|
+
- Table
|
|
232
|
+
- Version
|
|
233
|
+
- Status
|
|
234
|
+
- Source
|
|
235
|
+
- Drift state
|
|
236
|
+
- Environment
|
|
237
|
+
- Last applied
|
|
238
|
+
|
|
239
|
+
### Trigger Detail Page
|
|
240
|
+
- Summary panel
|
|
241
|
+
- SQL diff
|
|
242
|
+
- Registry state
|
|
243
|
+
|
|
244
|
+
### Actions (State-Based)
|
|
245
|
+
- Enable
|
|
246
|
+
- Disable
|
|
247
|
+
- Drop
|
|
248
|
+
- Re-execute
|
|
249
|
+
- Execute SQL capsule
|
|
250
|
+
|
|
251
|
+
Buttons must:
|
|
252
|
+
- Be permission-aware
|
|
253
|
+
- Be env-aware
|
|
254
|
+
- Respect kill switch
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## 9. Drop & Re-Execute Flow (CRITICAL)
|
|
259
|
+
|
|
260
|
+
Re-execute must:
|
|
261
|
+
1. Show diff
|
|
262
|
+
2. Require reason
|
|
263
|
+
3. Require typed confirmation
|
|
264
|
+
4. Execute transactionally
|
|
265
|
+
5. Update registry
|
|
266
|
+
|
|
267
|
+
No silent operations allowed.
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## 10. What This Gem Is NOT
|
|
272
|
+
|
|
273
|
+
- Not a raw SQL editor
|
|
274
|
+
- Not a trigger playground
|
|
275
|
+
- Not auto-executing
|
|
276
|
+
- Not unsafe
|
|
277
|
+
- Not magic
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## 11. Non-Negotiable Constraints
|
|
282
|
+
|
|
283
|
+
- No silent prod changes
|
|
284
|
+
- No hidden state
|
|
285
|
+
- No bypassing registry
|
|
286
|
+
- No bypassing permissions
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## 12. Final Framing (VERY IMPORTANT)
|
|
291
|
+
|
|
292
|
+
This gem must be described as:
|
|
293
|
+
|
|
294
|
+
> **A PostgreSQL Trigger Control Plane for Rails**
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 samaswin
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|