pg_sql_triggers 1.0.0 → 1.0.1
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/.erb_lint.yml +47 -0
- data/.rubocop.yml +4 -1
- data/CHANGELOG.md +29 -1
- data/Goal.md +408 -123
- data/README.md +47 -215
- data/app/controllers/pg_sql_triggers/application_controller.rb +46 -0
- data/app/controllers/pg_sql_triggers/generator_controller.rb +10 -4
- data/app/controllers/pg_sql_triggers/migrations_controller.rb +18 -0
- data/app/models/pg_sql_triggers/trigger_registry.rb +20 -2
- data/app/views/layouts/pg_sql_triggers/application.html.erb +34 -1
- data/app/views/pg_sql_triggers/dashboard/index.html.erb +70 -30
- data/app/views/pg_sql_triggers/generator/new.html.erb +4 -4
- data/app/views/pg_sql_triggers/generator/preview.html.erb +14 -6
- data/app/views/pg_sql_triggers/shared/_confirmation_modal.html.erb +189 -0
- data/app/views/pg_sql_triggers/shared/_kill_switch_status.html.erb +40 -0
- data/app/views/pg_sql_triggers/tables/index.html.erb +0 -2
- data/app/views/pg_sql_triggers/tables/show.html.erb +3 -4
- data/db/migrate/20251222000001_create_pg_sql_triggers_tables.rb +1 -1
- data/docs/README.md +66 -0
- data/docs/api-reference.md +663 -0
- data/docs/configuration.md +541 -0
- data/docs/getting-started.md +135 -0
- data/docs/kill-switch.md +586 -0
- data/docs/screenshots/.gitkeep +1 -0
- data/docs/screenshots/Generate Trigger.png +0 -0
- data/docs/screenshots/Triggers Page.png +0 -0
- data/docs/screenshots/kill error.png +0 -0
- data/docs/screenshots/kill modal for migration down.png +0 -0
- data/docs/usage-guide.md +420 -0
- data/docs/web-ui.md +339 -0
- data/lib/generators/pg_sql_triggers/templates/create_pg_sql_triggers_tables.rb +1 -1
- data/lib/generators/pg_sql_triggers/templates/initializer.rb +36 -2
- data/lib/pg_sql_triggers/generator/service.rb +1 -1
- data/lib/pg_sql_triggers/migration.rb +1 -1
- data/lib/pg_sql_triggers/migrator.rb +27 -3
- data/lib/pg_sql_triggers/registry/manager.rb +6 -6
- data/lib/pg_sql_triggers/sql/kill_switch.rb +300 -0
- data/lib/pg_sql_triggers/testing/dry_run.rb +5 -7
- data/lib/pg_sql_triggers/testing/safe_executor.rb +23 -11
- data/lib/pg_sql_triggers/version.rb +1 -1
- data/lib/pg_sql_triggers.rb +12 -0
- data/lib/tasks/trigger_migrations.rake +33 -0
- metadata +35 -5
data/Goal.md
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
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
|
## 1. Problem Statement
|
|
11
2
|
|
|
12
3
|
Rails teams use PostgreSQL triggers for:
|
|
@@ -42,7 +33,7 @@ This gem **manages lifecycle**, not business logic.
|
|
|
42
33
|
|
|
43
34
|
## 3. Supported Capabilities (MUST IMPLEMENT)
|
|
44
35
|
|
|
45
|
-
### A. Trigger Declaration (DSL)
|
|
36
|
+
### A. Trigger Declaration (DSL) ✅
|
|
46
37
|
|
|
47
38
|
Developers declare triggers using Ruby DSL:
|
|
48
39
|
|
|
@@ -60,97 +51,97 @@ end
|
|
|
60
51
|
```
|
|
61
52
|
|
|
62
53
|
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
|
|
54
|
+
- ~~DSL generates metadata, NOT raw SQL~~
|
|
55
|
+
- ~~Every trigger has a version~~
|
|
56
|
+
- ~~Triggers are environment-aware~~
|
|
57
|
+
- ~~Triggers can be enabled or disabled~~
|
|
67
58
|
|
|
68
59
|
---
|
|
69
60
|
|
|
70
|
-
### B. Trigger Generation
|
|
61
|
+
### B. Trigger Generation ✅
|
|
71
62
|
|
|
72
63
|
The gem must generate triggers safely.
|
|
73
64
|
|
|
74
65
|
Generators create:
|
|
75
|
-
1. Trigger DSL file
|
|
76
|
-
2. Function stub (PL/pgSQL)
|
|
77
|
-
3. Manifest metadata
|
|
66
|
+
1. ~~Trigger DSL file~~
|
|
67
|
+
2. ~~Function stub (PL/pgSQL)~~
|
|
68
|
+
3. ~~Manifest metadata~~
|
|
78
69
|
|
|
79
70
|
Rules:
|
|
80
|
-
- Generated triggers are **disabled by default
|
|
81
|
-
- Nothing executes automatically
|
|
82
|
-
- Developers must explicitly apply
|
|
71
|
+
- ~~Generated triggers are **disabled by default**~~
|
|
72
|
+
- ~~Nothing executes automatically~~
|
|
73
|
+
- ~~Developers must explicitly apply~~
|
|
83
74
|
|
|
84
75
|
---
|
|
85
76
|
|
|
86
|
-
### C. Trigger Registry (Source of Truth)
|
|
77
|
+
### C. Trigger Registry (Source of Truth) ✅
|
|
87
78
|
|
|
88
79
|
All triggers must be tracked in a registry table.
|
|
89
80
|
|
|
90
81
|
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
|
|
82
|
+
- ~~trigger_name~~
|
|
83
|
+
- ~~table_name~~
|
|
84
|
+
- ~~version~~
|
|
85
|
+
- ~~enabled~~
|
|
86
|
+
- ~~checksum~~ (⚠️ partially - uses placeholder in registry manager)
|
|
87
|
+
- ~~source (dsl / generated / manual_sql)~~
|
|
88
|
+
- ~~environment~~
|
|
89
|
+
- ~~installed_at~~
|
|
90
|
+
- ~~last_verified_at~~
|
|
100
91
|
|
|
101
92
|
Rails must always know:
|
|
102
|
-
- what exists
|
|
103
|
-
- how it was created
|
|
104
|
-
- whether it drifted
|
|
93
|
+
- ~~what exists~~
|
|
94
|
+
- ~~how it was created~~
|
|
95
|
+
- ⚠️ whether it drifted (drift detection not fully implemented)
|
|
105
96
|
|
|
106
97
|
---
|
|
107
98
|
|
|
108
|
-
### D. Safe Apply & Deploy
|
|
99
|
+
### D. Safe Apply & Deploy ❌ (not implemented)
|
|
109
100
|
|
|
110
101
|
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
|
|
102
|
+
- ⚠️ Run in a transaction (migrations use transactions, but no explicit "apply" method)
|
|
103
|
+
- ❌ Diff expected vs actual (not implemented)
|
|
104
|
+
- ⚠️ Never blindly DROP + CREATE (migrations handle this, but no explicit safety checks)
|
|
105
|
+
- ⚠️ Support rollback on failure (migration rollback exists, but not explicit apply rollback)
|
|
106
|
+
- ⚠️ Update registry atomically (registry updated but not in explicit apply method)
|
|
116
107
|
|
|
117
108
|
---
|
|
118
109
|
|
|
119
|
-
### E. Drift Detection
|
|
110
|
+
### E. Drift Detection ⚠️ (autoloaded but implementation missing)
|
|
120
111
|
|
|
121
112
|
System must detect:
|
|
122
|
-
- Missing triggers
|
|
123
|
-
- Version mismatch
|
|
124
|
-
- Function body drift
|
|
125
|
-
- Manual SQL overrides
|
|
126
|
-
- Unknown external triggers
|
|
113
|
+
- ❌ Missing triggers (not implemented)
|
|
114
|
+
- ❌ Version mismatch (not implemented)
|
|
115
|
+
- ❌ Function body drift (not implemented)
|
|
116
|
+
- ❌ Manual SQL overrides (not implemented)
|
|
117
|
+
- ❌ Unknown external triggers (not implemented)
|
|
127
118
|
|
|
128
119
|
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)
|
|
120
|
+
1. ❌ Managed & In Sync (constants defined, logic missing)
|
|
121
|
+
2. ❌ Managed & Drifted (constants defined, logic missing)
|
|
122
|
+
3. ❌ Manual Override (constants defined, logic missing)
|
|
123
|
+
4. ❌ Disabled (constants defined, logic missing)
|
|
124
|
+
5. ❌ Dropped (Recorded) (constants defined, logic missing)
|
|
125
|
+
6. ❌ Unknown (External) (constants defined, logic missing)
|
|
135
126
|
|
|
136
127
|
---
|
|
137
128
|
|
|
138
|
-
### F. Rails Console Introspection
|
|
129
|
+
### F. Rails Console Introspection ✅
|
|
139
130
|
|
|
140
131
|
Provide console APIs:
|
|
141
132
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
133
|
+
~~PgSqlTriggers::Registry.list~~ (note: namespace differs slightly from goal)
|
|
134
|
+
~~PgSqlTriggers::Registry.enabled~~
|
|
135
|
+
~~PgSqlTriggers::Registry.disabled~~
|
|
136
|
+
~~PgSqlTriggers::Registry.for_table(:users)~~
|
|
137
|
+
~~PgSqlTriggers::Registry.diff~~ (⚠️ calls drift detection which is not fully implemented)
|
|
138
|
+
~~PgSqlTriggers::Registry.validate!~~
|
|
148
139
|
|
|
149
|
-
No raw SQL required by users
|
|
140
|
+
~~No raw SQL required by users.~~
|
|
150
141
|
|
|
151
142
|
---
|
|
152
143
|
|
|
153
|
-
## 4. Free-Form SQL Execution (MANDATORY)
|
|
144
|
+
## 4. Free-Form SQL Execution (MANDATORY) ❌ (routes exist but implementation missing)
|
|
154
145
|
|
|
155
146
|
The gem MUST support free-form SQL execution.
|
|
156
147
|
|
|
@@ -163,62 +154,109 @@ This is required for:
|
|
|
163
154
|
|
|
164
155
|
Free-form SQL is wrapped in **named SQL capsules**:
|
|
165
156
|
|
|
166
|
-
- Must be named
|
|
167
|
-
- Must declare environment
|
|
168
|
-
- Must declare purpose
|
|
169
|
-
- Must be applied explicitly
|
|
157
|
+
- ❌ Must be named (routes exist, implementation missing)
|
|
158
|
+
- ❌ Must declare environment (not implemented)
|
|
159
|
+
- ❌ Must declare purpose (not implemented)
|
|
160
|
+
- ❌ Must be applied explicitly (not implemented)
|
|
170
161
|
|
|
171
162
|
Rules:
|
|
172
|
-
- Runs in a transaction
|
|
173
|
-
- Checksum verified
|
|
174
|
-
- Registry updated
|
|
175
|
-
- Marked as `source = manual_sql`
|
|
163
|
+
- ❌ Runs in a transaction (not implemented)
|
|
164
|
+
- ❌ Checksum verified (not implemented)
|
|
165
|
+
- ❌ Registry updated (not implemented)
|
|
166
|
+
- ❌ Marked as `source = manual_sql` (not implemented)
|
|
176
167
|
|
|
177
168
|
---
|
|
178
169
|
|
|
179
|
-
## 5. Permissions Model v1
|
|
170
|
+
## 5. Permissions Model v1 ⚠️ (structure exists, not enforced)
|
|
180
171
|
|
|
181
172
|
Three permission levels:
|
|
182
173
|
|
|
183
174
|
### Viewer
|
|
184
|
-
- Read-only
|
|
185
|
-
- View triggers
|
|
186
|
-
- View diffs
|
|
175
|
+
- ~~Read-only~~ (structure exists)
|
|
176
|
+
- ~~View triggers~~
|
|
177
|
+
- ~~View diffs~~
|
|
187
178
|
|
|
188
179
|
### Operator
|
|
189
|
-
- Enable / Disable triggers
|
|
190
|
-
- Apply generated triggers
|
|
191
|
-
- Re-execute triggers in non-prod
|
|
192
|
-
- Dry-run SQL
|
|
180
|
+
- ~~Enable / Disable triggers~~ (structure exists)
|
|
181
|
+
- ~~Apply generated triggers~~
|
|
182
|
+
- ~~Re-execute triggers in non-prod~~
|
|
183
|
+
- ~~Dry-run SQL~~
|
|
193
184
|
|
|
194
185
|
### Admin
|
|
195
|
-
- Drop triggers
|
|
196
|
-
- Execute free-form SQL
|
|
197
|
-
- Re-execute triggers in any env
|
|
198
|
-
- Override drift
|
|
186
|
+
- ~~Drop triggers~~ (structure exists)
|
|
187
|
+
- ~~Execute free-form SQL~~
|
|
188
|
+
- ~~Re-execute triggers in any env~~
|
|
189
|
+
- ~~Override drift~~
|
|
199
190
|
|
|
200
191
|
Permissions enforced in:
|
|
201
|
-
- UI
|
|
202
|
-
- CLI
|
|
203
|
-
- Console
|
|
192
|
+
- ❌ UI (not enforced)
|
|
193
|
+
- ❌ CLI (not enforced)
|
|
194
|
+
- ❌ Console (not enforced)
|
|
204
195
|
|
|
205
196
|
---
|
|
206
197
|
|
|
207
|
-
## 6. Kill Switch for Production SQL (MANDATORY)
|
|
198
|
+
## 6. Kill Switch for Production SQL (MANDATORY) ✅
|
|
208
199
|
|
|
209
200
|
Production mutations must be gated.
|
|
210
201
|
|
|
211
202
|
### Levels:
|
|
212
|
-
1. Global disable (default)
|
|
213
|
-
2. Runtime ENV override
|
|
214
|
-
3. Explicit confirmation text
|
|
215
|
-
4. Optional time-window auto-lock
|
|
203
|
+
1. ~~Global disable (default)~~ ✅ (fully implemented)
|
|
204
|
+
2. ~~Runtime ENV override~~ ✅ (implemented via KILL_SWITCH_OVERRIDE and CONFIRMATION_TEXT)
|
|
205
|
+
3. ~~Explicit confirmation text~~ ✅ (implemented with customizable patterns)
|
|
206
|
+
4. ❌ Optional time-window auto-lock (not implemented - optional feature)
|
|
216
207
|
|
|
217
208
|
Kill switch must:
|
|
218
|
-
- Block UI
|
|
219
|
-
- Block CLI
|
|
220
|
-
- Block console
|
|
221
|
-
- Always log attempts
|
|
209
|
+
- ~~Block UI~~ ✅ (implemented in MigrationsController and GeneratorController)
|
|
210
|
+
- ~~Block CLI~~ ✅ (implemented in all rake tasks)
|
|
211
|
+
- ~~Block console~~ ✅ (implemented in TriggerRegistry and Migrator)
|
|
212
|
+
- ~~Always log attempts~~ ✅ (comprehensive logging with operation, environment, actor, and status)
|
|
213
|
+
|
|
214
|
+
### Implementation Details:
|
|
215
|
+
|
|
216
|
+
**Core Module**: `lib/pg_sql_triggers/sql/kill_switch.rb`
|
|
217
|
+
- Thread-safe override mechanism using thread-local storage
|
|
218
|
+
- Configuration-driven with sensible defaults
|
|
219
|
+
- Operation-specific confirmation patterns
|
|
220
|
+
- Comprehensive logging and audit trail
|
|
221
|
+
|
|
222
|
+
**Protected Operations**:
|
|
223
|
+
- CLI: All trigger migration tasks (migrate, rollback, up, down, redo)
|
|
224
|
+
- CLI: Combined db:migrate:with_triggers tasks
|
|
225
|
+
- Console: TriggerRegistry#enable!, TriggerRegistry#disable!
|
|
226
|
+
- Console: Migrator.run_up, Migrator.run_down
|
|
227
|
+
- UI: Migration up/down/redo actions
|
|
228
|
+
- UI: Trigger generation
|
|
229
|
+
|
|
230
|
+
**Configuration**: `config/initializers/pg_sql_triggers.rb`
|
|
231
|
+
- kill_switch_enabled: Global enable/disable (default: true)
|
|
232
|
+
- kill_switch_environments: Protected environments (default: [:production, :staging])
|
|
233
|
+
- kill_switch_confirmation_required: Require confirmation text (default: true)
|
|
234
|
+
- kill_switch_confirmation_pattern: Custom confirmation pattern lambda
|
|
235
|
+
- kill_switch_logger: Logger for events (default: Rails.logger)
|
|
236
|
+
|
|
237
|
+
**Usage Examples**:
|
|
238
|
+
```bash
|
|
239
|
+
# CLI with confirmation
|
|
240
|
+
KILL_SWITCH_OVERRIDE=true CONFIRMATION_TEXT="EXECUTE TRIGGER_MIGRATE" rake trigger:migrate
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
```ruby
|
|
244
|
+
# Console with override block
|
|
245
|
+
PgSqlTriggers::SQL::KillSwitch.override(confirmation: "EXECUTE TRIGGER_ENABLE") do
|
|
246
|
+
trigger.enable!
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
# Console with direct confirmation
|
|
250
|
+
trigger.enable!(confirmation: "EXECUTE TRIGGER_ENABLE")
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
**Tests**: Comprehensive test suite at `spec/pg_sql_triggers/sql/kill_switch_spec.rb` covering:
|
|
254
|
+
- Environment detection
|
|
255
|
+
- Confirmation validation
|
|
256
|
+
- Override mechanisms (thread-local, ENV, explicit)
|
|
257
|
+
- Thread safety
|
|
258
|
+
- Logging
|
|
259
|
+
- Custom configuration
|
|
222
260
|
|
|
223
261
|
---
|
|
224
262
|
|
|
@@ -226,43 +264,43 @@ Kill switch must:
|
|
|
226
264
|
|
|
227
265
|
UI is operational, not decorative.
|
|
228
266
|
|
|
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
|
|
267
|
+
### Dashboard ✅ (partial)
|
|
268
|
+
- ~~Trigger name~~
|
|
269
|
+
- ~~Table~~
|
|
270
|
+
- ~~Version~~
|
|
271
|
+
- ~~Status~~
|
|
272
|
+
- ~~Source~~
|
|
273
|
+
- ⚠️ Drift state (displayed but drift detection not fully implemented)
|
|
274
|
+
- ~~Environment~~
|
|
275
|
+
- ⚠️ Last applied (installed_at exists but not displayed)
|
|
276
|
+
|
|
277
|
+
### Trigger Detail Page ❌ (not implemented)
|
|
278
|
+
- ❌ Summary panel (trigger info shown in tables/show but no dedicated page)
|
|
279
|
+
- ❌ SQL diff
|
|
280
|
+
- ❌ Registry state
|
|
281
|
+
|
|
282
|
+
### Actions (State-Based) ⚠️ (structure exists, not fully implemented)
|
|
283
|
+
- ⚠️ Enable (method exists but no UI buttons/flow)
|
|
284
|
+
- ⚠️ Disable (method exists but no UI buttons/flow)
|
|
285
|
+
- ❌ Drop (not implemented)
|
|
286
|
+
- ❌ Re-execute (not implemented)
|
|
287
|
+
- ❌ Execute SQL capsule (not implemented)
|
|
250
288
|
|
|
251
289
|
Buttons must:
|
|
252
|
-
- Be permission-aware
|
|
253
|
-
- Be env-aware
|
|
254
|
-
- Respect kill switch
|
|
290
|
+
- ❌ Be permission-aware (permissions defined but not enforced in UI)
|
|
291
|
+
- ❌ Be env-aware (not implemented)
|
|
292
|
+
- ✅ Respect kill switch (kill switch fully implemented - see Section 6)
|
|
255
293
|
|
|
256
294
|
---
|
|
257
295
|
|
|
258
|
-
## 9. Drop & Re-Execute Flow (CRITICAL)
|
|
296
|
+
## 9. Drop & Re-Execute Flow (CRITICAL) ❌ (not implemented)
|
|
259
297
|
|
|
260
298
|
Re-execute must:
|
|
261
|
-
1. Show diff
|
|
262
|
-
2. Require reason
|
|
263
|
-
3. Require typed confirmation
|
|
264
|
-
4. Execute transactionally
|
|
265
|
-
5. Update registry
|
|
299
|
+
1. ❌ Show diff (not implemented)
|
|
300
|
+
2. ❌ Require reason (not implemented)
|
|
301
|
+
3. ❌ Require typed confirmation (not implemented)
|
|
302
|
+
4. ❌ Execute transactionally (not implemented)
|
|
303
|
+
5. ❌ Update registry (not implemented)
|
|
266
304
|
|
|
267
305
|
No silent operations allowed.
|
|
268
306
|
|
|
@@ -292,3 +330,250 @@ No silent operations allowed.
|
|
|
292
330
|
This gem must be described as:
|
|
293
331
|
|
|
294
332
|
> **A PostgreSQL Trigger Control Plane for Rails**
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## 13. Implementation Status & Improvements Needed
|
|
337
|
+
|
|
338
|
+
### ✅ Achieved Features
|
|
339
|
+
|
|
340
|
+
**Core Infrastructure:**
|
|
341
|
+
- ✅ Trigger Declaration DSL (`PgSqlTriggers::DSL.pg_sql_trigger`) - Section 3.A
|
|
342
|
+
- ✅ Trigger Registry model and table with all required fields - Section 3.C
|
|
343
|
+
- ✅ Trigger Generation (form-based wizard, DSL + migration files) - Section 3.B
|
|
344
|
+
- ✅ Database Introspection (tables, triggers, columns) - Supporting infrastructure
|
|
345
|
+
- ✅ Trigger Migrations system (rake tasks + UI) - Supporting infrastructure
|
|
346
|
+
- ✅ Rails Console Introspection APIs (`PgSqlTriggers::Registry.*`) - Section 3.F
|
|
347
|
+
- ✅ Enable/Disable trigger methods on TriggerRegistry model - Basic functionality
|
|
348
|
+
- ✅ Kill Switch for Production Safety (fully implemented) - Section 6
|
|
349
|
+
- ✅ Mountable Rails Engine with routes - Supporting infrastructure
|
|
350
|
+
- ✅ Basic UI (Dashboard, Tables view, Generator) - Section 8 (Dashboard partial)
|
|
351
|
+
|
|
352
|
+
**From Section 3.A (Trigger Declaration DSL):**
|
|
353
|
+
- ✅ DSL generates metadata
|
|
354
|
+
- ✅ Every trigger has a version
|
|
355
|
+
- ✅ Triggers are environment-aware
|
|
356
|
+
- ✅ Triggers can be enabled or disabled
|
|
357
|
+
|
|
358
|
+
**From Section 3.B (Trigger Generation):**
|
|
359
|
+
- ✅ Generator creates trigger DSL file
|
|
360
|
+
- ✅ Generator creates function stub (PL/pgSQL)
|
|
361
|
+
- ✅ Generator creates manifest metadata
|
|
362
|
+
- ✅ Generated triggers are disabled by default
|
|
363
|
+
|
|
364
|
+
**From Section 3.C (Trigger Registry):**
|
|
365
|
+
- ✅ Registry tracks: trigger_name, table_name, version, enabled, source, environment, installed_at, last_verified_at
|
|
366
|
+
- ✅ Registry tracks checksum (⚠️ partially - uses placeholder in registry manager)
|
|
367
|
+
- ✅ Rails knows what exists and how it was created
|
|
368
|
+
|
|
369
|
+
**From Section 3.F (Rails Console Introspection):**
|
|
370
|
+
- ✅ `PgSqlTriggers::Registry.list` (note: namespace differs slightly from goal)
|
|
371
|
+
- ✅ `PgSqlTriggers::Registry.enabled`
|
|
372
|
+
- ✅ `PgSqlTriggers::Registry.disabled`
|
|
373
|
+
- ✅ `PgSqlTriggers::Registry.for_table(:users)`
|
|
374
|
+
- ✅ `PgSqlTriggers::Registry.validate!`
|
|
375
|
+
- ✅ No raw SQL required by users for basic operations
|
|
376
|
+
|
|
377
|
+
**From Section 5 (Permissions Model):**
|
|
378
|
+
- ✅ Permission structure exists (Viewer, Operator, Admin roles defined)
|
|
379
|
+
- ✅ Permission model classes exist
|
|
380
|
+
|
|
381
|
+
**From Section 6 (Kill Switch):**
|
|
382
|
+
- ✅ Fully implemented - see Section 6 for details
|
|
383
|
+
- ✅ Global disable configuration (default: true)
|
|
384
|
+
- ✅ Runtime ENV override support (KILL_SWITCH_OVERRIDE)
|
|
385
|
+
- ✅ Explicit confirmation text requirement
|
|
386
|
+
- ✅ Comprehensive logging and audit trail
|
|
387
|
+
- ✅ UI, CLI, and Console enforcement
|
|
388
|
+
- ✅ Thread-safe override mechanism
|
|
389
|
+
|
|
390
|
+
**From Section 8 (UI):**
|
|
391
|
+
- ✅ Dashboard with: Trigger name, Table, Version, Status, Source, Environment
|
|
392
|
+
- ✅ Dashboard displays drift state (⚠️ drift detection not fully implemented)
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
### 🔴 HIGH PRIORITY - Critical Missing Features
|
|
397
|
+
|
|
398
|
+
#### 1. Drift Detection (Section 3.E)
|
|
399
|
+
**Priority:** HIGH - Core functionality
|
|
400
|
+
|
|
401
|
+
**Status:** Autoloaded but implementation files missing
|
|
402
|
+
|
|
403
|
+
**Missing Files:**
|
|
404
|
+
- ❌ `lib/pg_sql_triggers/drift/detector.rb` - Drift detection logic
|
|
405
|
+
- ❌ `lib/pg_sql_triggers/drift/reporter.rb` - Drift reporting
|
|
406
|
+
|
|
407
|
+
**Missing Functionality:**
|
|
408
|
+
- ❌ Detection of missing triggers
|
|
409
|
+
- ❌ Version mismatch detection
|
|
410
|
+
- ❌ Function body drift detection
|
|
411
|
+
- ❌ Manual SQL override detection
|
|
412
|
+
- ❌ Unknown external trigger detection
|
|
413
|
+
- ❌ All 6 drift states properly implemented (Managed & In Sync, Managed & Drifted, Manual Override, Disabled, Dropped (Recorded), Unknown (External))
|
|
414
|
+
|
|
415
|
+
#### 2. Safe Apply & Deploy (Section 3.D)
|
|
416
|
+
**Priority:** HIGH - Deployment safety
|
|
417
|
+
|
|
418
|
+
**Status:** Not implemented
|
|
419
|
+
|
|
420
|
+
**Missing:**
|
|
421
|
+
- ❌ Safe apply method that runs in a transaction
|
|
422
|
+
- ❌ Diff expected vs actual state before applying
|
|
423
|
+
- ❌ Explicit safety checks (never blindly DROP + CREATE)
|
|
424
|
+
- ❌ Rollback on failure with registry rollback
|
|
425
|
+
- ❌ Atomic registry update
|
|
426
|
+
- ❌ Integration with migrations and generator service
|
|
427
|
+
|
|
428
|
+
#### 3. Drop & Re-Execute Flow (CRITICAL - Section 9)
|
|
429
|
+
**Priority:** HIGH - Operational requirements
|
|
430
|
+
|
|
431
|
+
**Status:** Not implemented
|
|
432
|
+
|
|
433
|
+
**Missing:**
|
|
434
|
+
- ❌ Drop trigger functionality with permission checks, kill switch, reason, typed confirmation
|
|
435
|
+
- ❌ Re-execute functionality with diff display, reason, typed confirmation
|
|
436
|
+
- ❌ UI for drop/re-execute actions
|
|
437
|
+
- ❌ Confirmation dialogs with typed confirmation text
|
|
438
|
+
- ❌ Transactional execution and registry update
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
### 🟡 MEDIUM PRIORITY - User-Facing Features
|
|
443
|
+
|
|
444
|
+
#### 4. SQL Capsules (MANDATORY - Section 4)
|
|
445
|
+
**Priority:** MEDIUM - Emergency operations
|
|
446
|
+
|
|
447
|
+
**Status:** Routes exist but implementation missing
|
|
448
|
+
|
|
449
|
+
**Missing Files:**
|
|
450
|
+
- ❌ `lib/pg_sql_triggers/sql/capsule.rb` - SQL capsule definition class
|
|
451
|
+
- ❌ `lib/pg_sql_triggers/sql/executor.rb` - SQL execution with transaction, checksum, registry update
|
|
452
|
+
- ❌ `app/controllers/pg_sql_triggers/sql_capsules_controller.rb` - UI controller
|
|
453
|
+
- ❌ SQL capsule views (new, show, create)
|
|
454
|
+
- ❌ SQL capsule storage mechanism
|
|
455
|
+
|
|
456
|
+
**Requirements to implement:**
|
|
457
|
+
- Named SQL capsules with environment and purpose declaration
|
|
458
|
+
- Explicit application workflow
|
|
459
|
+
- Transactional execution
|
|
460
|
+
- Checksum verification
|
|
461
|
+
- Registry update with `source = manual_sql`
|
|
462
|
+
|
|
463
|
+
#### 5. Trigger Detail Page (Section 8 - UI)
|
|
464
|
+
**Priority:** MEDIUM - Usability
|
|
465
|
+
|
|
466
|
+
**Status:** Partial (shown in tables/show but not dedicated page)
|
|
467
|
+
|
|
468
|
+
**Missing:**
|
|
469
|
+
- ❌ Dedicated trigger detail route and controller action
|
|
470
|
+
- ❌ Summary panel with all trigger metadata
|
|
471
|
+
- ❌ SQL diff view (expected vs actual)
|
|
472
|
+
- ❌ Registry state display
|
|
473
|
+
- ❌ Action buttons (Enable/Disable/Drop/Re-execute/Execute SQL capsule)
|
|
474
|
+
- ❌ Permission-aware, environment-aware, kill switch-aware button visibility
|
|
475
|
+
|
|
476
|
+
#### 6. UI Actions & Permissions Enforcement (Section 8)
|
|
477
|
+
**Priority:** MEDIUM - Usability & security
|
|
478
|
+
|
|
479
|
+
**Status:** Structure exists but not fully enforced
|
|
480
|
+
|
|
481
|
+
**Missing:**
|
|
482
|
+
- ❌ Enable/Disable buttons in dashboard and detail pages
|
|
483
|
+
- ❌ Drop button (Admin only)
|
|
484
|
+
- ❌ Re-execute button with flow
|
|
485
|
+
- ❌ Execute SQL capsule button (Admin only)
|
|
486
|
+
- ❌ Permission checking in controllers
|
|
487
|
+
- ❌ Permission checking in UI (hide/disable buttons)
|
|
488
|
+
- ✅ Kill switch enforcement in UI (fully implemented - see Section 6)
|
|
489
|
+
- ❌ Environment awareness in UI actions
|
|
490
|
+
|
|
491
|
+
---
|
|
492
|
+
|
|
493
|
+
### 🟢 LOW PRIORITY - Polish & Improvements
|
|
494
|
+
|
|
495
|
+
#### 8. Console/CLI Permission Enforcement (Section 5)
|
|
496
|
+
**Priority:** LOW - Security polish
|
|
497
|
+
|
|
498
|
+
**Status:** Not enforced
|
|
499
|
+
|
|
500
|
+
**Missing:**
|
|
501
|
+
- ❌ Permission checks in `TriggerRegistry#enable!` and `disable!`
|
|
502
|
+
- ❌ Permission checks in rake tasks
|
|
503
|
+
- ❌ Permission checks in console APIs
|
|
504
|
+
- ❌ Actor context passing through all operations
|
|
505
|
+
|
|
506
|
+
#### 9. Checksum Implementation Consistency
|
|
507
|
+
**Priority:** LOW - Technical debt
|
|
508
|
+
|
|
509
|
+
**Status:** Partially implemented
|
|
510
|
+
|
|
511
|
+
**Issues:**
|
|
512
|
+
- ⚠️ Registry manager uses "placeholder" checksum instead of calculating real checksum
|
|
513
|
+
- ✅ Generator service calculates checksum correctly
|
|
514
|
+
- ⚠️ Need consistent checksum calculation across all creation paths
|
|
515
|
+
|
|
516
|
+
**Fix Required:**
|
|
517
|
+
- Replace "placeholder" in `Registry::Manager.register` with actual checksum calculation
|
|
518
|
+
- Ensure checksum is calculated consistently (same algorithm as generator)
|
|
519
|
+
|
|
520
|
+
#### 10. Enhanced Logging & Audit Trail
|
|
521
|
+
**Priority:** LOW - Operational polish
|
|
522
|
+
|
|
523
|
+
**Status:** Kill switch logging is comprehensive; audit trail could be enhanced
|
|
524
|
+
|
|
525
|
+
**Missing:**
|
|
526
|
+
- ✅ Kill switch activation attempts logging (fully implemented)
|
|
527
|
+
- ✅ Kill switch overrides logging (fully implemented)
|
|
528
|
+
- ⚠️ Comprehensive audit trail table for production operation attempts (optional enhancement - logging exists but structured audit table would be better)
|
|
529
|
+
|
|
530
|
+
#### 11. Error Handling Consistency
|
|
531
|
+
**Priority:** LOW - Code quality
|
|
532
|
+
|
|
533
|
+
**Status:** Kill switch errors are properly implemented; other error types need consistency
|
|
534
|
+
|
|
535
|
+
**Missing:**
|
|
536
|
+
- ✅ Kill switch violations raise `KillSwitchError` (fully implemented)
|
|
537
|
+
- ❌ Permission violations should raise `PermissionError`
|
|
538
|
+
- ❌ Drift issues should raise `DriftError`
|
|
539
|
+
- ❌ Consistent error handling across all operations
|
|
540
|
+
|
|
541
|
+
#### 12. Testing Coverage
|
|
542
|
+
**Priority:** LOW - Quality assurance
|
|
543
|
+
|
|
544
|
+
**Status:** Kill switch has comprehensive tests; other areas need coverage
|
|
545
|
+
|
|
546
|
+
**Missing:**
|
|
547
|
+
- ❌ SQL capsules need tests
|
|
548
|
+
- ✅ Kill switch has comprehensive tests (fully tested)
|
|
549
|
+
- ❌ Drift detection needs tests
|
|
550
|
+
- ❌ Permission enforcement needs tests
|
|
551
|
+
- ❌ Drop/re-execute flow needs tests
|
|
552
|
+
|
|
553
|
+
#### 13. Documentation Updates
|
|
554
|
+
**Priority:** LOW - User experience
|
|
555
|
+
|
|
556
|
+
**Status:** Kill switch is well documented; other areas need documentation
|
|
557
|
+
|
|
558
|
+
**Missing:**
|
|
559
|
+
- ❌ README mentions SQL capsules but no implementation details
|
|
560
|
+
- ✅ README includes kill switch documentation with enforcement details (fully documented)
|
|
561
|
+
- ❌ Need examples for SQL capsules
|
|
562
|
+
- ❌ Need examples for permission configuration
|
|
563
|
+
|
|
564
|
+
#### 14. Partial Implementation Notes
|
|
565
|
+
**Priority:** LOW - Known issues
|
|
566
|
+
|
|
567
|
+
- ⚠️ Permissions Model - Structure exists but not enforced in UI/CLI/console
|
|
568
|
+
- ✅ Kill Switch - Fully implemented (see Section 6 for details)
|
|
569
|
+
- ⚠️ Checksum - Implemented in generator service correctly, but Registry::Manager.register uses "placeholder" (needs fix for DSL-registered triggers)
|
|
570
|
+
- ⚠️ Drift Detection - Constants defined, Detector and Reporter classes missing
|
|
571
|
+
- ⚠️ Dashboard - Drift state displayed but drift detection not fully implemented (will work once drift detection is implemented)
|
|
572
|
+
- ⚠️ Dashboard - Last applied (installed_at exists in registry but not displayed in UI)
|
|
573
|
+
- ⚠️ `PgSqlTriggers::Registry.diff` - Calls drift detection which is not fully implemented
|
|
574
|
+
|
|
575
|
+
---
|
|
576
|
+
|
|
577
|
+
### 📝 Technical Notes
|
|
578
|
+
|
|
579
|
+
1. **Console API Naming:** Goal shows `PgSqlTrigger.list` but implementation is `PgSqlTriggers::Registry.list` (current is better, just note the difference)
|