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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.erb_lint.yml +47 -0
  3. data/.rubocop.yml +4 -1
  4. data/CHANGELOG.md +29 -1
  5. data/Goal.md +408 -123
  6. data/README.md +47 -215
  7. data/app/controllers/pg_sql_triggers/application_controller.rb +46 -0
  8. data/app/controllers/pg_sql_triggers/generator_controller.rb +10 -4
  9. data/app/controllers/pg_sql_triggers/migrations_controller.rb +18 -0
  10. data/app/models/pg_sql_triggers/trigger_registry.rb +20 -2
  11. data/app/views/layouts/pg_sql_triggers/application.html.erb +34 -1
  12. data/app/views/pg_sql_triggers/dashboard/index.html.erb +70 -30
  13. data/app/views/pg_sql_triggers/generator/new.html.erb +4 -4
  14. data/app/views/pg_sql_triggers/generator/preview.html.erb +14 -6
  15. data/app/views/pg_sql_triggers/shared/_confirmation_modal.html.erb +189 -0
  16. data/app/views/pg_sql_triggers/shared/_kill_switch_status.html.erb +40 -0
  17. data/app/views/pg_sql_triggers/tables/index.html.erb +0 -2
  18. data/app/views/pg_sql_triggers/tables/show.html.erb +3 -4
  19. data/db/migrate/20251222000001_create_pg_sql_triggers_tables.rb +1 -1
  20. data/docs/README.md +66 -0
  21. data/docs/api-reference.md +663 -0
  22. data/docs/configuration.md +541 -0
  23. data/docs/getting-started.md +135 -0
  24. data/docs/kill-switch.md +586 -0
  25. data/docs/screenshots/.gitkeep +1 -0
  26. data/docs/screenshots/Generate Trigger.png +0 -0
  27. data/docs/screenshots/Triggers Page.png +0 -0
  28. data/docs/screenshots/kill error.png +0 -0
  29. data/docs/screenshots/kill modal for migration down.png +0 -0
  30. data/docs/usage-guide.md +420 -0
  31. data/docs/web-ui.md +339 -0
  32. data/lib/generators/pg_sql_triggers/templates/create_pg_sql_triggers_tables.rb +1 -1
  33. data/lib/generators/pg_sql_triggers/templates/initializer.rb +36 -2
  34. data/lib/pg_sql_triggers/generator/service.rb +1 -1
  35. data/lib/pg_sql_triggers/migration.rb +1 -1
  36. data/lib/pg_sql_triggers/migrator.rb +27 -3
  37. data/lib/pg_sql_triggers/registry/manager.rb +6 -6
  38. data/lib/pg_sql_triggers/sql/kill_switch.rb +300 -0
  39. data/lib/pg_sql_triggers/testing/dry_run.rb +5 -7
  40. data/lib/pg_sql_triggers/testing/safe_executor.rb +23 -11
  41. data/lib/pg_sql_triggers/version.rb +1 -1
  42. data/lib/pg_sql_triggers.rb +12 -0
  43. data/lib/tasks/trigger_migrations.rake +33 -0
  44. 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
- PgSqlTrigger.list
143
- PgSqlTrigger.enabled
144
- PgSqlTrigger.disabled
145
- PgSqlTrigger.for_table(:users)
146
- PgSqlTrigger.diff
147
- PgSqlTrigger.validate!
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)