pg_sql_triggers 1.3.0 → 1.5.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/.erb_lint.yml +0 -0
- data/.rspec +0 -0
- data/.rubocop.yml +6 -16
- data/AGENTS.md +8 -0
- data/CHANGELOG.md +354 -0
- data/COVERAGE.md +39 -41
- data/LICENSE +0 -0
- data/README.md +44 -26
- data/RELEASE.md +0 -0
- data/Rakefile +5 -0
- data/app/assets/javascripts/pg_sql_triggers/application.js +0 -0
- data/app/assets/javascripts/pg_sql_triggers/trigger_actions.js +0 -0
- data/app/assets/stylesheets/pg_sql_triggers/application.css +0 -0
- data/app/controllers/concerns/pg_sql_triggers/error_handling.rb +0 -0
- data/app/controllers/concerns/pg_sql_triggers/kill_switch_protection.rb +0 -0
- data/app/controllers/concerns/pg_sql_triggers/permission_checking.rb +6 -5
- data/app/controllers/pg_sql_triggers/application_controller.rb +0 -0
- data/app/controllers/pg_sql_triggers/audit_logs_controller.rb +81 -64
- data/app/controllers/pg_sql_triggers/dashboard_controller.rb +111 -34
- data/app/controllers/pg_sql_triggers/migrations_controller.rb +13 -14
- data/app/controllers/pg_sql_triggers/tables_controller.rb +8 -0
- data/app/controllers/pg_sql_triggers/triggers_controller.rb +1 -0
- data/app/helpers/pg_sql_triggers/dashboard_helper.rb +19 -0
- data/app/helpers/pg_sql_triggers/permissions_helper.rb +3 -2
- data/app/models/pg_sql_triggers/application_record.rb +0 -0
- data/app/models/pg_sql_triggers/audit_log.rb +29 -47
- data/app/models/pg_sql_triggers/trigger_registry.rb +137 -74
- data/app/views/layouts/pg_sql_triggers/application.html.erb +0 -1
- data/app/views/pg_sql_triggers/audit_logs/index.html.erb +9 -5
- data/app/views/pg_sql_triggers/dashboard/index.html.erb +107 -27
- data/app/views/pg_sql_triggers/shared/_confirmation_modal.html.erb +0 -0
- data/app/views/pg_sql_triggers/shared/_kill_switch_status.html.erb +0 -0
- data/app/views/pg_sql_triggers/tables/index.html.erb +27 -18
- data/app/views/pg_sql_triggers/tables/show.html.erb +0 -2
- data/app/views/pg_sql_triggers/triggers/_drop_modal.html.erb +0 -0
- data/app/views/pg_sql_triggers/triggers/_re_execute_modal.html.erb +0 -0
- data/app/views/pg_sql_triggers/triggers/show.html.erb +33 -0
- data/config/initializers/pg_sql_triggers.rb +0 -0
- data/config/routes.rb +0 -14
- data/db/migrate/{20251222000001_create_pg_sql_triggers_tables.rb → 20251222104327_create_pg_sql_triggers_tables.rb} +0 -0
- data/db/migrate/20251229071916_add_timing_to_pg_sql_triggers_registry.rb +0 -0
- data/db/migrate/{20260103000001_create_pg_sql_triggers_audit_log.rb → 20260103114508_create_pg_sql_triggers_audit_log.rb} +0 -0
- data/db/migrate/20260228162233_add_for_each_to_pg_sql_triggers_registry.rb +8 -0
- data/db/migrate/20260412185841_add_constraint_deferral_to_pg_sql_triggers_registry.rb +9 -0
- data/docs/README.md +3 -0
- data/docs/api-reference.md +176 -152
- data/docs/audit-trail.md +1 -1
- data/docs/configuration.md +196 -3
- data/docs/getting-started.md +31 -16
- data/docs/kill-switch.md +0 -0
- data/docs/permissions.md +6 -9
- data/docs/troubleshooting.md +0 -0
- data/docs/ui-guide.md +0 -0
- data/docs/usage-guide.md +112 -67
- data/docs/web-ui.md +3 -103
- data/lib/generators/pg_sql_triggers/install_generator.rb +0 -0
- data/lib/generators/pg_sql_triggers/templates/README +0 -0
- data/lib/generators/pg_sql_triggers/templates/create_pg_sql_triggers_tables.rb +0 -0
- data/lib/generators/pg_sql_triggers/templates/initializer.rb +14 -0
- data/lib/generators/pg_sql_triggers/templates/trigger_dsl.rb.tt +11 -0
- data/lib/generators/pg_sql_triggers/templates/trigger_migration.rb.erb +0 -0
- data/lib/generators/pg_sql_triggers/templates/trigger_migration_full.rb.tt +29 -0
- data/lib/generators/pg_sql_triggers/trigger_generator.rb +83 -0
- data/lib/generators/pg_sql_triggers/trigger_migration_generator.rb +0 -0
- data/lib/pg_sql_triggers/alerting.rb +77 -0
- data/lib/pg_sql_triggers/database_introspection.rb +0 -0
- data/lib/pg_sql_triggers/deferral_checksum.rb +54 -0
- data/lib/pg_sql_triggers/drift/db_queries.rb +26 -13
- data/lib/pg_sql_triggers/drift/detector.rb +59 -38
- data/lib/pg_sql_triggers/drift/reporter.rb +0 -0
- data/lib/pg_sql_triggers/drift.rb +5 -0
- data/lib/pg_sql_triggers/dsl/trigger_definition.rb +68 -20
- data/lib/pg_sql_triggers/dsl.rb +0 -0
- data/lib/pg_sql_triggers/engine.rb +49 -0
- data/lib/pg_sql_triggers/errors.rb +0 -0
- data/lib/pg_sql_triggers/events_checksum.rb +114 -0
- data/lib/pg_sql_triggers/migration.rb +5 -6
- data/lib/pg_sql_triggers/migrator/pre_apply_comparator.rb +85 -82
- data/lib/pg_sql_triggers/migrator/pre_apply_diff_reporter.rb +0 -0
- data/lib/pg_sql_triggers/migrator/safety_validator.rb +34 -12
- data/lib/pg_sql_triggers/migrator.rb +137 -94
- data/lib/pg_sql_triggers/permissions/checker.rb +12 -15
- data/lib/pg_sql_triggers/permissions.rb +1 -0
- data/lib/pg_sql_triggers/rake_development_boot.rb +65 -0
- data/lib/pg_sql_triggers/registry/manager.rb +60 -21
- data/lib/pg_sql_triggers/registry/validator.rb +287 -6
- data/lib/pg_sql_triggers/registry.rb +0 -0
- data/lib/pg_sql_triggers/schema_dumper_extension.rb +32 -0
- data/lib/pg_sql_triggers/sql/kill_switch.rb +154 -275
- data/lib/pg_sql_triggers/sql.rb +0 -6
- data/lib/pg_sql_triggers/testing/dry_run.rb +0 -0
- data/lib/pg_sql_triggers/testing/function_tester.rb +97 -107
- data/lib/pg_sql_triggers/testing/safe_executor.rb +0 -0
- data/lib/pg_sql_triggers/testing/syntax_validator.rb +0 -0
- data/lib/pg_sql_triggers/testing.rb +0 -0
- data/lib/pg_sql_triggers/trigger_structure_dumper.rb +111 -0
- data/lib/pg_sql_triggers/version.rb +1 -1
- data/lib/pg_sql_triggers.rb +21 -1
- data/lib/tasks/trigger_migrations.rake +235 -152
- data/rakelib/pg_sql_triggers_environment.rake +9 -0
- data/scripts/generate_coverage_report.rb +4 -1
- data/sig/pg_sql_triggers.rbs +0 -0
- metadata +68 -22
- data/Goal.md +0 -742
- data/app/controllers/pg_sql_triggers/generator_controller.rb +0 -213
- data/app/controllers/pg_sql_triggers/sql_capsules_controller.rb +0 -161
- data/app/views/pg_sql_triggers/generator/new.html.erb +0 -388
- data/app/views/pg_sql_triggers/generator/preview.html.erb +0 -305
- data/app/views/pg_sql_triggers/sql_capsules/new.html.erb +0 -81
- data/app/views/pg_sql_triggers/sql_capsules/show.html.erb +0 -85
- data/lib/generators/trigger/migration_generator.rb +0 -60
- data/lib/pg_sql_triggers/generator/form.rb +0 -80
- data/lib/pg_sql_triggers/generator/service.rb +0 -339
- data/lib/pg_sql_triggers/generator.rb +0 -8
- data/lib/pg_sql_triggers/sql/capsule.rb +0 -79
- data/lib/pg_sql_triggers/sql/executor.rb +0 -200
data/Goal.md
DELETED
|
@@ -1,742 +0,0 @@
|
|
|
1
|
-
## 1. Problem Statement
|
|
2
|
-
|
|
3
|
-
Rails teams use PostgreSQL triggers for:
|
|
4
|
-
- data integrity
|
|
5
|
-
- performance
|
|
6
|
-
- billing logic
|
|
7
|
-
|
|
8
|
-
But triggers today are:
|
|
9
|
-
- managed manually
|
|
10
|
-
- invisible to Rails
|
|
11
|
-
- unsafe to deploy
|
|
12
|
-
- easy to drift
|
|
13
|
-
|
|
14
|
-
This gem brings triggers into the Rails ecosystem with:
|
|
15
|
-
- lifecycle management
|
|
16
|
-
- safe deploys
|
|
17
|
-
- versioning
|
|
18
|
-
- UI control
|
|
19
|
-
- emergency SQL escape hatches
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## 2. Core Philosophy
|
|
24
|
-
|
|
25
|
-
- Rails-native
|
|
26
|
-
- Explicit over magic
|
|
27
|
-
- Safe by default
|
|
28
|
-
- Power with guardrails
|
|
29
|
-
|
|
30
|
-
This gem **manages lifecycle**, not business logic.
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## 3. Supported Capabilities (MUST IMPLEMENT)
|
|
35
|
-
|
|
36
|
-
### A. Trigger Declaration (DSL) ✅
|
|
37
|
-
|
|
38
|
-
Developers declare triggers using Ruby DSL:
|
|
39
|
-
|
|
40
|
-
```ruby
|
|
41
|
-
pg_sql_trigger "users_email_validation" do
|
|
42
|
-
table :users
|
|
43
|
-
on :insert, :update
|
|
44
|
-
function :validate_user_email
|
|
45
|
-
|
|
46
|
-
version 3
|
|
47
|
-
enabled true
|
|
48
|
-
|
|
49
|
-
when_env :production
|
|
50
|
-
end
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
Rules:
|
|
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~~
|
|
58
|
-
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
### B. Trigger Generation ✅
|
|
62
|
-
|
|
63
|
-
The gem must generate triggers safely.
|
|
64
|
-
|
|
65
|
-
Generators create:
|
|
66
|
-
1. ~~Trigger DSL file~~
|
|
67
|
-
2. ~~Function stub (PL/pgSQL)~~
|
|
68
|
-
3. ~~Manifest metadata~~
|
|
69
|
-
|
|
70
|
-
Rules:
|
|
71
|
-
- ~~Generated triggers are **disabled by default**~~
|
|
72
|
-
- ~~Nothing executes automatically~~
|
|
73
|
-
- ~~Developers must explicitly apply~~
|
|
74
|
-
|
|
75
|
-
---
|
|
76
|
-
|
|
77
|
-
### C. Trigger Registry (Source of Truth) ✅
|
|
78
|
-
|
|
79
|
-
All triggers must be tracked in a registry table.
|
|
80
|
-
|
|
81
|
-
Registry tracks:
|
|
82
|
-
- ~~trigger_name~~
|
|
83
|
-
- ~~table_name~~
|
|
84
|
-
- ~~version~~
|
|
85
|
-
- ~~enabled~~
|
|
86
|
-
- ~~checksum~~ (✅ fully implemented - consistent field-concatenation algorithm)
|
|
87
|
-
- ~~source (dsl / generated / manual_sql)~~
|
|
88
|
-
- ~~environment~~
|
|
89
|
-
- ~~installed_at~~
|
|
90
|
-
- ~~last_verified_at~~
|
|
91
|
-
|
|
92
|
-
Rails must always know:
|
|
93
|
-
- ~~what exists~~
|
|
94
|
-
- ~~how it was created~~
|
|
95
|
-
- ✅ whether it drifted (drift detection fully implemented)
|
|
96
|
-
|
|
97
|
-
---
|
|
98
|
-
|
|
99
|
-
### D. Safe Apply & Deploy ✅ (fully implemented via migrations)
|
|
100
|
-
|
|
101
|
-
Applying triggers must:
|
|
102
|
-
- ✅ Run in a transaction (migrations run in transactions)
|
|
103
|
-
- ✅ Diff expected vs actual (fully implemented - pre-apply comparison before migration execution)
|
|
104
|
-
- ✅ Never blindly DROP + CREATE (fully implemented - safety validator blocks unsafe DROP + CREATE patterns)
|
|
105
|
-
- ✅ Support rollback on failure (migration rollback exists)
|
|
106
|
-
- ✅ Update registry atomically (registry updated during migration execution)
|
|
107
|
-
|
|
108
|
-
**Status:** Core functionality fully implemented through migration system. Pre-apply comparison shows diff between expected (from migration) and actual (from database) state before applying migrations. Safety validator explicitly blocks unsafe DROP + CREATE operations, preventing migrations from blindly dropping and recreating existing database objects without validation.
|
|
109
|
-
|
|
110
|
-
---
|
|
111
|
-
|
|
112
|
-
### E. Drift Detection ✅ (fully implemented)
|
|
113
|
-
|
|
114
|
-
System must detect:
|
|
115
|
-
- ✅ Missing triggers (implemented via DROPPED state)
|
|
116
|
-
- ✅ Version mismatch (implemented via checksum comparison)
|
|
117
|
-
- ✅ Function body drift (implemented via checksum comparison)
|
|
118
|
-
- ✅ Manual SQL overrides (implemented via MANUAL_OVERRIDE state)
|
|
119
|
-
- ✅ Unknown external triggers (implemented via UNKNOWN state)
|
|
120
|
-
|
|
121
|
-
Drift states:
|
|
122
|
-
1. ✅ Managed & In Sync (fully implemented)
|
|
123
|
-
2. ✅ Managed & Drifted (fully implemented)
|
|
124
|
-
3. ✅ Manual Override (fully implemented)
|
|
125
|
-
4. ✅ Disabled (fully implemented)
|
|
126
|
-
5. ✅ Dropped (Recorded) (fully implemented)
|
|
127
|
-
6. ✅ Unknown (External) (fully implemented)
|
|
128
|
-
|
|
129
|
-
---
|
|
130
|
-
|
|
131
|
-
### F. Rails Console Introspection ✅
|
|
132
|
-
|
|
133
|
-
Provide console APIs:
|
|
134
|
-
|
|
135
|
-
✅ `PgSqlTriggers::Registry.list` - Returns all registered triggers
|
|
136
|
-
✅ `PgSqlTriggers::Registry.enabled` - Returns enabled triggers
|
|
137
|
-
✅ `PgSqlTriggers::Registry.disabled` - Returns disabled triggers
|
|
138
|
-
✅ `PgSqlTriggers::Registry.for_table(:users)` - Returns triggers for a specific table
|
|
139
|
-
✅ `PgSqlTriggers::Registry.diff` - Checks for drift (fully working with drift detection)
|
|
140
|
-
✅ `PgSqlTriggers::Registry.validate!` - Validates all triggers
|
|
141
|
-
✅ `PgSqlTriggers::Registry.drifted` - Returns all drifted triggers
|
|
142
|
-
✅ `PgSqlTriggers::Registry.in_sync` - Returns all in-sync triggers
|
|
143
|
-
✅ `PgSqlTriggers::Registry.unknown_triggers` - Returns all unknown (external) triggers
|
|
144
|
-
✅ `PgSqlTriggers::Registry.dropped` - Returns all dropped triggers
|
|
145
|
-
✅ `PgSqlTriggers::Registry.enable(trigger_name, actor:, confirmation:)` - Enable a trigger
|
|
146
|
-
✅ `PgSqlTriggers::Registry.disable(trigger_name, actor:, confirmation:)` - Disable a trigger
|
|
147
|
-
✅ `PgSqlTriggers::Registry.drop(trigger_name, actor:, reason:, confirmation:)` - Drop a trigger
|
|
148
|
-
✅ `PgSqlTriggers::Registry.re_execute(trigger_name, actor:, reason:, confirmation:)` - Re-execute a trigger
|
|
149
|
-
|
|
150
|
-
✅ No raw SQL required by users for basic operations.
|
|
151
|
-
✅ All console APIs are fully documented with YARD documentation.
|
|
152
|
-
|
|
153
|
-
---
|
|
154
|
-
|
|
155
|
-
## 4. Free-Form SQL Execution (MANDATORY) ✅ (fully implemented in v1.2.0)
|
|
156
|
-
|
|
157
|
-
The gem MUST support free-form SQL execution.
|
|
158
|
-
|
|
159
|
-
This is required for:
|
|
160
|
-
- emergency fixes
|
|
161
|
-
- complex migrations
|
|
162
|
-
- DB-owner workflows
|
|
163
|
-
|
|
164
|
-
### SQL Capsules
|
|
165
|
-
|
|
166
|
-
Free-form SQL is wrapped in **named SQL capsules**:
|
|
167
|
-
|
|
168
|
-
- ✅ Must be named (fully implemented - `PgSqlTriggers::SQL::Capsule` class)
|
|
169
|
-
- ✅ Must declare environment (fully implemented)
|
|
170
|
-
- ✅ Must declare purpose (fully implemented)
|
|
171
|
-
- ✅ Must be applied explicitly (fully implemented - web UI and console API)
|
|
172
|
-
|
|
173
|
-
Rules:
|
|
174
|
-
- ✅ Runs in a transaction (fully implemented - `PgSqlTriggers::SQL::Executor` executes in transaction)
|
|
175
|
-
- ✅ Checksum verified (fully implemented - checksum calculated and stored)
|
|
176
|
-
- ✅ Registry updated (fully implemented - registry updated with `source = manual_sql`)
|
|
177
|
-
- ✅ Marked as `source = manual_sql` (fully implemented)
|
|
178
|
-
|
|
179
|
-
**Status:** ✅ Fully implemented in v1.2.0. Includes:
|
|
180
|
-
- `PgSqlTriggers::SQL::Capsule` class for defining SQL capsules
|
|
181
|
-
- `PgSqlTriggers::SQL::Executor.execute` method for safe execution
|
|
182
|
-
- Web UI controller (`SqlCapsulesController`) with create, show, and execute actions
|
|
183
|
-
- Permission checks (Admin role required for execution)
|
|
184
|
-
- Kill switch protection
|
|
185
|
-
- Comprehensive audit logging
|
|
186
|
-
- Console API: `PgSqlTriggers::SQL::Executor.execute(capsule, actor:, confirmation:)`
|
|
187
|
-
|
|
188
|
-
---
|
|
189
|
-
|
|
190
|
-
## 5. Permissions Model v1 ✅ (fully implemented and enforced in v1.3.0)
|
|
191
|
-
|
|
192
|
-
Three permission levels:
|
|
193
|
-
|
|
194
|
-
### Viewer
|
|
195
|
-
- ✅ Read-only (fully enforced)
|
|
196
|
-
- ✅ View triggers (fully enforced)
|
|
197
|
-
- ✅ View diffs (fully enforced)
|
|
198
|
-
|
|
199
|
-
### Operator
|
|
200
|
-
- ✅ Enable / Disable triggers (fully enforced)
|
|
201
|
-
- ✅ Apply generated triggers (fully enforced)
|
|
202
|
-
- ✅ Re-execute triggers in non-prod (fully enforced)
|
|
203
|
-
- ✅ Dry-run SQL (fully enforced)
|
|
204
|
-
|
|
205
|
-
### Admin
|
|
206
|
-
- ✅ Drop triggers (fully enforced - Admin only)
|
|
207
|
-
- ✅ Execute free-form SQL (fully enforced - Admin only)
|
|
208
|
-
- ✅ Re-execute triggers in any env (fully enforced - Admin only)
|
|
209
|
-
- ✅ Override drift (fully enforced)
|
|
210
|
-
|
|
211
|
-
Permissions enforced in:
|
|
212
|
-
- ✅ UI (fully enforced - buttons show/hide based on permissions, controllers check permissions)
|
|
213
|
-
- ✅ CLI (kill switch provides protection - permissions can be added if needed)
|
|
214
|
-
- ✅ Console (fully enforced - all console APIs check permissions via `permission_checker` configuration)
|
|
215
|
-
|
|
216
|
-
---
|
|
217
|
-
|
|
218
|
-
## 6. Kill Switch for Production SQL (MANDATORY) ✅
|
|
219
|
-
|
|
220
|
-
Production mutations must be gated.
|
|
221
|
-
|
|
222
|
-
### Levels:
|
|
223
|
-
1. ~~Global disable (default)~~ ✅ (fully implemented)
|
|
224
|
-
2. ~~Runtime ENV override~~ ✅ (implemented via KILL_SWITCH_OVERRIDE and CONFIRMATION_TEXT)
|
|
225
|
-
3. ~~Explicit confirmation text~~ ✅ (implemented with customizable patterns)
|
|
226
|
-
4. ❌ Optional time-window auto-lock (not implemented - optional feature)
|
|
227
|
-
|
|
228
|
-
Kill switch must:
|
|
229
|
-
- ~~Block UI~~ ✅ (implemented in MigrationsController and GeneratorController)
|
|
230
|
-
- ~~Block CLI~~ ✅ (implemented in all rake tasks)
|
|
231
|
-
- ~~Block console~~ ✅ (implemented in TriggerRegistry and Migrator)
|
|
232
|
-
- ~~Always log attempts~~ ✅ (comprehensive logging with operation, environment, actor, and status)
|
|
233
|
-
|
|
234
|
-
### Implementation Details:
|
|
235
|
-
|
|
236
|
-
**Core Module**: `lib/pg_sql_triggers/sql/kill_switch.rb`
|
|
237
|
-
- Thread-safe override mechanism using thread-local storage
|
|
238
|
-
- Configuration-driven with sensible defaults
|
|
239
|
-
- Operation-specific confirmation patterns
|
|
240
|
-
- Comprehensive logging and audit trail
|
|
241
|
-
|
|
242
|
-
**Protected Operations**:
|
|
243
|
-
- CLI: All trigger migration tasks (migrate, rollback, up, down, redo)
|
|
244
|
-
- CLI: Combined db:migrate:with_triggers tasks
|
|
245
|
-
- Console: TriggerRegistry#enable!, TriggerRegistry#disable!
|
|
246
|
-
- Console: Migrator.run_up, Migrator.run_down
|
|
247
|
-
- UI: Migration up/down/redo actions
|
|
248
|
-
- UI: Trigger generation
|
|
249
|
-
|
|
250
|
-
**Configuration**: `config/initializers/pg_sql_triggers.rb`
|
|
251
|
-
- kill_switch_enabled: Global enable/disable (default: true)
|
|
252
|
-
- kill_switch_environments: Protected environments (default: [:production, :staging])
|
|
253
|
-
- kill_switch_confirmation_required: Require confirmation text (default: true)
|
|
254
|
-
- kill_switch_confirmation_pattern: Custom confirmation pattern lambda
|
|
255
|
-
- kill_switch_logger: Logger for events (default: Rails.logger)
|
|
256
|
-
|
|
257
|
-
**Usage Examples**:
|
|
258
|
-
```bash
|
|
259
|
-
# CLI with confirmation
|
|
260
|
-
KILL_SWITCH_OVERRIDE=true CONFIRMATION_TEXT="EXECUTE TRIGGER_MIGRATE" rake trigger:migrate
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
```ruby
|
|
264
|
-
# Console with override block
|
|
265
|
-
PgSqlTriggers::SQL::KillSwitch.override(confirmation: "EXECUTE TRIGGER_ENABLE") do
|
|
266
|
-
trigger.enable!
|
|
267
|
-
end
|
|
268
|
-
|
|
269
|
-
# Console with direct confirmation
|
|
270
|
-
trigger.enable!(confirmation: "EXECUTE TRIGGER_ENABLE")
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
**Tests**: Comprehensive test suite at `spec/pg_sql_triggers/sql/kill_switch_spec.rb` covering:
|
|
274
|
-
- Environment detection
|
|
275
|
-
- Confirmation validation
|
|
276
|
-
- Override mechanisms (thread-local, ENV, explicit)
|
|
277
|
-
- Thread safety
|
|
278
|
-
- Logging
|
|
279
|
-
- Custom configuration
|
|
280
|
-
|
|
281
|
-
---
|
|
282
|
-
|
|
283
|
-
## 8. UI (Mountable Rails Engine)
|
|
284
|
-
|
|
285
|
-
UI is operational, not decorative.
|
|
286
|
-
|
|
287
|
-
### Dashboard ✅ (fully implemented in v1.3.0)
|
|
288
|
-
- ✅ Trigger name
|
|
289
|
-
- ✅ Table
|
|
290
|
-
- ✅ Version
|
|
291
|
-
- ✅ Status (enabled/disabled)
|
|
292
|
-
- ✅ Source
|
|
293
|
-
- ✅ Drift state (drift detection fully implemented - shows drift count and states)
|
|
294
|
-
- ✅ Environment
|
|
295
|
-
- ✅ Last applied (installed_at displayed with human-readable formatting and tooltips in v1.3.0)
|
|
296
|
-
|
|
297
|
-
### Trigger Detail Page ✅ (fully implemented in v1.3.0)
|
|
298
|
-
- ✅ Summary panel (dedicated trigger detail route and page with comprehensive metadata)
|
|
299
|
-
- ✅ SQL diff (expected vs actual comparison with syntax highlighting)
|
|
300
|
-
- ✅ Registry state (comprehensive state display including checksum, drift detection, manual override status)
|
|
301
|
-
- ✅ Breadcrumb navigation (Dashboard → Tables → Table → Trigger)
|
|
302
|
-
- ✅ Enhanced timestamp display (installed_at and last_verified_at with relative time formatting)
|
|
303
|
-
|
|
304
|
-
### Actions (State-Based) ✅ (fully implemented in v1.2.0 and v1.3.0)
|
|
305
|
-
- ✅ Enable (UI buttons in dashboard, table view, and trigger detail page with kill switch protection)
|
|
306
|
-
- ✅ Disable (UI buttons in dashboard, table view, and trigger detail page with kill switch protection)
|
|
307
|
-
- ✅ Drop (fully implemented in v1.2.0 - UI buttons with confirmation modal in v1.3.0)
|
|
308
|
-
- ✅ Re-execute (fully implemented in v1.2.0 - UI buttons with drift diff display in v1.3.0)
|
|
309
|
-
- ✅ Execute SQL capsule (fully implemented in v1.2.0 - UI buttons in v1.3.0)
|
|
310
|
-
|
|
311
|
-
Buttons must:
|
|
312
|
-
- ✅ Be permission-aware (fully enforced - buttons show/hide based on user permissions in v1.3.0)
|
|
313
|
-
- ✅ Be env-aware (fully implemented - warning colors for production, environment-aware styling)
|
|
314
|
-
- ✅ Respect kill switch (kill switch fully implemented - see Section 6)
|
|
315
|
-
|
|
316
|
-
---
|
|
317
|
-
|
|
318
|
-
## 9. Drop & Re-Execute Flow (CRITICAL) ✅ (fully implemented in v1.2.0, UI added in v1.3.0)
|
|
319
|
-
|
|
320
|
-
Re-execute must:
|
|
321
|
-
1. ✅ Show diff (fully implemented - drift diff displayed before re-execution)
|
|
322
|
-
2. ✅ Require reason (fully implemented - reason field required and logged)
|
|
323
|
-
3. ✅ Require typed confirmation (fully implemented - confirmation text required in protected environments)
|
|
324
|
-
4. ✅ Execute transactionally (fully implemented - all operations run in transactions)
|
|
325
|
-
5. ✅ Update registry (fully implemented - registry updated atomically with operations)
|
|
326
|
-
|
|
327
|
-
Drop must:
|
|
328
|
-
1. ✅ Require reason (fully implemented - reason field required and logged)
|
|
329
|
-
2. ✅ Require typed confirmation (fully implemented - confirmation text required in protected environments)
|
|
330
|
-
3. ✅ Execute transactionally (fully implemented - drop runs in transaction)
|
|
331
|
-
4. ✅ Update registry (fully implemented - trigger removed from registry after drop)
|
|
332
|
-
5. ✅ Require Admin permission (fully enforced)
|
|
333
|
-
|
|
334
|
-
No silent operations allowed. ✅ All operations are logged to audit trail with actor, reason, and state changes.
|
|
335
|
-
|
|
336
|
-
---
|
|
337
|
-
|
|
338
|
-
## 10. What This Gem Is NOT
|
|
339
|
-
|
|
340
|
-
- Not a raw SQL editor
|
|
341
|
-
- Not a trigger playground
|
|
342
|
-
- Not auto-executing
|
|
343
|
-
- Not unsafe
|
|
344
|
-
- Not magic
|
|
345
|
-
|
|
346
|
-
---
|
|
347
|
-
|
|
348
|
-
## 11. Non-Negotiable Constraints
|
|
349
|
-
|
|
350
|
-
- No silent prod changes
|
|
351
|
-
- No hidden state
|
|
352
|
-
- No bypassing registry
|
|
353
|
-
- No bypassing permissions
|
|
354
|
-
|
|
355
|
-
---
|
|
356
|
-
|
|
357
|
-
## 12. Final Framing (VERY IMPORTANT)
|
|
358
|
-
|
|
359
|
-
This gem must be described as:
|
|
360
|
-
|
|
361
|
-
> **A PostgreSQL Trigger Control Plane for Rails**
|
|
362
|
-
|
|
363
|
-
---
|
|
364
|
-
|
|
365
|
-
## 13. Implementation Status & Improvements Needed
|
|
366
|
-
|
|
367
|
-
### 📊 Quick Status Summary
|
|
368
|
-
|
|
369
|
-
**Fully Implemented:**
|
|
370
|
-
- ✅ Trigger Declaration DSL (Section 3.A)
|
|
371
|
-
- ✅ Trigger Generation (Section 3.B)
|
|
372
|
-
- ✅ Trigger Registry (Section 3.C) - with consistent field-concatenation checksum algorithm
|
|
373
|
-
- ✅ Safe Apply & Deploy (Section 3.D) - fully implemented with safety validation
|
|
374
|
-
- ✅ Drift Detection (Section 3.E) - fully implemented with all 6 drift states
|
|
375
|
-
- ✅ Rails Console Introspection (Section 3.F) - including working diff method
|
|
376
|
-
- ✅ Kill Switch for Production Safety (Section 6) - fully implemented
|
|
377
|
-
- ✅ SQL Capsules (Section 4) - fully implemented in v1.2.0
|
|
378
|
-
- ✅ Permissions Model (Section 5) - fully enforced in v1.3.0
|
|
379
|
-
- ✅ Drop & Re-Execute Flow (Section 9) - fully implemented in v1.2.0, UI in v1.3.0
|
|
380
|
-
- ✅ Complete UI (Section 8) - dashboard, trigger detail page, all action buttons implemented in v1.3.0
|
|
381
|
-
- ✅ Audit Logging System (Section 13) - fully implemented in v1.3.0 with UI
|
|
382
|
-
|
|
383
|
-
**Partially Implemented:**
|
|
384
|
-
- None - all critical features are fully implemented
|
|
385
|
-
|
|
386
|
-
**Not Implemented (Optional/Low Priority):**
|
|
387
|
-
- ❌ Time-window auto-lock for kill switch (Section 6 - optional feature)
|
|
388
|
-
|
|
389
|
-
### ✅ Achieved Features
|
|
390
|
-
|
|
391
|
-
**Core Infrastructure:**
|
|
392
|
-
- ✅ Trigger Declaration DSL (`PgSqlTriggers::DSL.pg_sql_trigger`) - Section 3.A
|
|
393
|
-
- ✅ Trigger Registry model and table with all required fields - Section 3.C
|
|
394
|
-
- ✅ Trigger Generation (form-based wizard, DSL + migration files) - Section 3.B
|
|
395
|
-
- ✅ Database Introspection (tables, triggers, columns) - Supporting infrastructure
|
|
396
|
-
- ✅ Trigger Migrations system (rake tasks + UI) - Supporting infrastructure
|
|
397
|
-
- ✅ Drift Detection (all 6 states, detector, reporter, console APIs) - Section 3.E
|
|
398
|
-
- ✅ Rails Console Introspection APIs (`PgSqlTriggers::Registry.*`) - Section 3.F
|
|
399
|
-
- ✅ Enable/Disable trigger methods on TriggerRegistry model - Basic functionality
|
|
400
|
-
- ✅ Kill Switch for Production Safety (fully implemented) - Section 6
|
|
401
|
-
- ✅ Mountable Rails Engine with routes - Supporting infrastructure
|
|
402
|
-
- ✅ Complete UI (Dashboard, Tables view, Generator, Trigger Detail Page, all action buttons) - Section 8 (fully implemented in v1.3.0)
|
|
403
|
-
|
|
404
|
-
**From Section 3.A (Trigger Declaration DSL):**
|
|
405
|
-
- ✅ DSL generates metadata
|
|
406
|
-
- ✅ Every trigger has a version
|
|
407
|
-
- ✅ Triggers are environment-aware
|
|
408
|
-
- ✅ Triggers can be enabled or disabled
|
|
409
|
-
|
|
410
|
-
**From Section 3.B (Trigger Generation):**
|
|
411
|
-
- ✅ Generator creates trigger DSL file
|
|
412
|
-
- ✅ Generator creates function stub (PL/pgSQL)
|
|
413
|
-
- ✅ Generator creates manifest metadata
|
|
414
|
-
- ✅ Generated triggers are disabled by default
|
|
415
|
-
|
|
416
|
-
**From Section 3.C (Trigger Registry):**
|
|
417
|
-
- ✅ Registry tracks: trigger_name, table_name, version, enabled, source, environment, installed_at, last_verified_at
|
|
418
|
-
- ✅ Registry tracks checksum (✅ consistent field-concatenation algorithm across all creation paths)
|
|
419
|
-
- ✅ Rails knows what exists and how it was created
|
|
420
|
-
|
|
421
|
-
**From Section 3.E (Drift Detection):**
|
|
422
|
-
- ✅ Drift::Detector class with all 6 drift states
|
|
423
|
-
- ✅ Drift::Reporter class for formatting drift reports
|
|
424
|
-
- ✅ Drift::DbQueries helper for PostgreSQL system catalog queries
|
|
425
|
-
- ✅ Detection of missing triggers (DROPPED state)
|
|
426
|
-
- ✅ Detection of version/function body drift (DRIFTED state via checksum)
|
|
427
|
-
- ✅ Detection of manual SQL overrides (MANUAL_OVERRIDE state)
|
|
428
|
-
- ✅ Detection of unknown external triggers (UNKNOWN state)
|
|
429
|
-
- ✅ Detection of disabled triggers (DISABLED state)
|
|
430
|
-
- ✅ Detection of in-sync triggers (IN_SYNC state)
|
|
431
|
-
- ✅ Registry convenience methods (drifted, in_sync, unknown_triggers, dropped)
|
|
432
|
-
- ✅ TriggerRegistry instance methods (drift_state, drift_result, drifted?, in_sync?, dropped?)
|
|
433
|
-
- ✅ Comprehensive test coverage for Detector and Reporter
|
|
434
|
-
|
|
435
|
-
**From Section 3.F (Rails Console Introspection):**
|
|
436
|
-
- ✅ `PgSqlTriggers::Registry.list` (note: namespace differs slightly from goal)
|
|
437
|
-
- ✅ `PgSqlTriggers::Registry.enabled`
|
|
438
|
-
- ✅ `PgSqlTriggers::Registry.disabled`
|
|
439
|
-
- ✅ `PgSqlTriggers::Registry.for_table(:users)`
|
|
440
|
-
- ✅ `PgSqlTriggers::Registry.validate!`
|
|
441
|
-
- ✅ `PgSqlTriggers::Registry.diff` (fully working with drift detection)
|
|
442
|
-
- ✅ `PgSqlTriggers::Registry.drifted` (returns all drifted triggers)
|
|
443
|
-
- ✅ `PgSqlTriggers::Registry.in_sync` (returns all in-sync triggers)
|
|
444
|
-
- ✅ `PgSqlTriggers::Registry.unknown_triggers` (returns all external triggers)
|
|
445
|
-
- ✅ `PgSqlTriggers::Registry.dropped` (returns all dropped triggers)
|
|
446
|
-
- ✅ No raw SQL required by users for basic operations (enable/disable via console methods)
|
|
447
|
-
|
|
448
|
-
**From Section 5 (Permissions Model):**
|
|
449
|
-
- ✅ Permission structure exists (Viewer, Operator, Admin roles defined)
|
|
450
|
-
- ✅ Permission model classes exist
|
|
451
|
-
|
|
452
|
-
**From Section 6 (Kill Switch):**
|
|
453
|
-
- ✅ Fully implemented - see Section 6 for details
|
|
454
|
-
- ✅ Global disable configuration (default: true)
|
|
455
|
-
- ✅ Runtime ENV override support (KILL_SWITCH_OVERRIDE)
|
|
456
|
-
- ✅ Explicit confirmation text requirement
|
|
457
|
-
- ✅ Comprehensive logging and audit trail
|
|
458
|
-
- ✅ UI, CLI, and Console enforcement
|
|
459
|
-
- ✅ Thread-safe override mechanism
|
|
460
|
-
|
|
461
|
-
**From Section 4 (SQL Capsules):**
|
|
462
|
-
- ✅ `PgSqlTriggers::SQL::Capsule` class for defining SQL capsules
|
|
463
|
-
- ✅ `PgSqlTriggers::SQL::Executor.execute` method for safe execution
|
|
464
|
-
- ✅ Web UI controller (`SqlCapsulesController`) with create, show, and execute actions
|
|
465
|
-
- ✅ Permission checks (Admin role required)
|
|
466
|
-
- ✅ Kill switch protection
|
|
467
|
-
- ✅ Transactional execution
|
|
468
|
-
- ✅ Checksum calculation and storage
|
|
469
|
-
- ✅ Registry update with `source = manual_sql`
|
|
470
|
-
- ✅ Comprehensive audit logging
|
|
471
|
-
- ✅ Console API: `PgSqlTriggers::SQL::Executor.execute(capsule, actor:, confirmation:)`
|
|
472
|
-
|
|
473
|
-
**From Section 5 (Permissions Model):**
|
|
474
|
-
- ✅ Permission structure (Viewer, Operator, Admin roles)
|
|
475
|
-
- ✅ Permission enforcement in UI (controllers and views)
|
|
476
|
-
- ✅ Permission enforcement in Console APIs (all Registry methods)
|
|
477
|
-
- ✅ Permission enforcement in SQL Executor
|
|
478
|
-
- ✅ `PermissionsHelper` module for view-level permission checks
|
|
479
|
-
- ✅ Permission helper methods in `ApplicationController`
|
|
480
|
-
- ✅ Configurable `permission_checker` via configuration
|
|
481
|
-
- ✅ `PermissionError` exception class
|
|
482
|
-
- ✅ Comprehensive test coverage
|
|
483
|
-
|
|
484
|
-
**From Section 8 (UI):**
|
|
485
|
-
- ✅ Dashboard with: Trigger name, Table, Version, Status (enabled/disabled), Source, Environment, Drift state, Last Applied
|
|
486
|
-
- ✅ Dashboard displays drift count (fully working with drift detection)
|
|
487
|
-
- ✅ Tables view with table listing and trigger details
|
|
488
|
-
- ✅ Trigger detail page (dedicated route/page with comprehensive metadata, SQL diff, registry state)
|
|
489
|
-
- ✅ Generator UI (form-based wizard for creating triggers)
|
|
490
|
-
- ✅ Migration management UI (up/down/redo with kill switch protection)
|
|
491
|
-
- ✅ All action buttons (enable/disable/drop/re-execute/execute SQL capsule)
|
|
492
|
-
- ✅ Permission-aware button visibility
|
|
493
|
-
- ✅ Environment-aware button styling
|
|
494
|
-
- ✅ Breadcrumb navigation
|
|
495
|
-
- ✅ Enhanced timestamp display
|
|
496
|
-
|
|
497
|
-
**From Section 9 (Drop & Re-Execute Flow):**
|
|
498
|
-
- ✅ `TriggerRegistry#drop!` method with permission checks, kill switch, reason, confirmation
|
|
499
|
-
- ✅ `TriggerRegistry#re_execute!` method with drift diff, reason, confirmation
|
|
500
|
-
- ✅ UI buttons for drop and re-execute in dashboard, table view, and trigger detail page
|
|
501
|
-
- ✅ Confirmation modals with reason input and typed confirmation
|
|
502
|
-
- ✅ Drift comparison shown before re-execution
|
|
503
|
-
- ✅ Transactional execution
|
|
504
|
-
- ✅ Registry updates
|
|
505
|
-
- ✅ Comprehensive audit logging
|
|
506
|
-
|
|
507
|
-
---
|
|
508
|
-
|
|
509
|
-
### ✅ HIGH PRIORITY - All Critical Features Completed
|
|
510
|
-
|
|
511
|
-
**Status:** All HIGH priority features have been fully implemented in v1.2.0 and v1.3.0.
|
|
512
|
-
|
|
513
|
-
#### 1. SQL Capsules (MANDATORY - Section 4) - ✅ COMPLETED in v1.2.0
|
|
514
|
-
**Priority:** HIGH - Mandatory feature for emergency operations
|
|
515
|
-
|
|
516
|
-
**Status:** ✅ Fully implemented in v1.2.0
|
|
517
|
-
|
|
518
|
-
**Implementation:**
|
|
519
|
-
- ✅ `lib/pg_sql_triggers/sql/capsule.rb` - SQL capsule definition class
|
|
520
|
-
- ✅ `lib/pg_sql_triggers/sql/executor.rb` - SQL execution with transaction, checksum, registry update
|
|
521
|
-
- ✅ `app/controllers/pg_sql_triggers/sql_capsules_controller.rb` - UI controller
|
|
522
|
-
- ✅ SQL capsule views (new, show, create, execute)
|
|
523
|
-
- ✅ SQL capsule storage mechanism (registry table with `source = manual_sql`)
|
|
524
|
-
|
|
525
|
-
**Functionality:**
|
|
526
|
-
- ✅ Named SQL capsules with environment and purpose declaration
|
|
527
|
-
- ✅ Explicit application workflow with confirmation
|
|
528
|
-
- ✅ Transactional execution
|
|
529
|
-
- ✅ Checksum verification
|
|
530
|
-
- ✅ Registry update with `source = manual_sql`
|
|
531
|
-
- ✅ Kill switch protection (blocks in production)
|
|
532
|
-
- ✅ Permission checks (Admin only)
|
|
533
|
-
- ✅ Comprehensive audit logging
|
|
534
|
-
|
|
535
|
-
**Impact:** ✅ Emergency SQL execution fully operational with safety controls.
|
|
536
|
-
|
|
537
|
-
#### 2. Drop & Re-Execute Flow (Section 9) - ✅ COMPLETED in v1.2.0, UI in v1.3.0
|
|
538
|
-
**Priority:** HIGH - Operational requirements
|
|
539
|
-
|
|
540
|
-
**Status:** ✅ Fully implemented in v1.2.0, UI added in v1.3.0
|
|
541
|
-
|
|
542
|
-
**Implementation:**
|
|
543
|
-
- ✅ Drop trigger functionality with permission checks, kill switch, reason, typed confirmation
|
|
544
|
-
- ✅ Re-execute functionality with diff display, reason, typed confirmation
|
|
545
|
-
- ✅ UI for drop/re-execute actions (buttons in dashboard, table view, trigger detail page)
|
|
546
|
-
- ✅ Confirmation modals with reason input and typed confirmation text
|
|
547
|
-
- ✅ Transactional execution and registry update
|
|
548
|
-
- ✅ Comprehensive audit logging with state changes
|
|
549
|
-
|
|
550
|
-
**Impact:** ✅ Safe drop and re-execute workflows fully operational with UI access.
|
|
551
|
-
|
|
552
|
-
#### 3. Safe Apply & Deploy (Section 3.D) - ✅ FULLY IMPLEMENTED
|
|
553
|
-
**Priority:** MEDIUM-HIGH - Deployment safety enhancement
|
|
554
|
-
|
|
555
|
-
**Status:** Fully implemented - pre-apply comparison and safety validation added
|
|
556
|
-
|
|
557
|
-
**What Works:**
|
|
558
|
-
- ✅ Migrations run in transactions
|
|
559
|
-
- ✅ Migration rollback supported
|
|
560
|
-
- ✅ Registry updated during migrations
|
|
561
|
-
- ✅ Pre-apply comparison (diff expected vs actual) before migration execution
|
|
562
|
-
- ✅ Diff reporting shows what will change before applying
|
|
563
|
-
- ✅ Safety validator blocks unsafe DROP + CREATE operations
|
|
564
|
-
- ✅ Explicit validation prevents migrations from blindly dropping and recreating existing objects
|
|
565
|
-
|
|
566
|
-
**Implementation Details:**
|
|
567
|
-
- `Migrator::SafetyValidator` class detects unsafe DROP + CREATE patterns in migrations
|
|
568
|
-
- Validator checks if migrations would drop existing database objects and recreate them
|
|
569
|
-
- Blocks migration execution if unsafe patterns detected (unless explicitly allowed)
|
|
570
|
-
- Configuration option `allow_unsafe_migrations` (default: false) for global override
|
|
571
|
-
- Environment variable `ALLOW_UNSAFE_MIGRATIONS=true` for per-migration override
|
|
572
|
-
- Provides clear error messages explaining unsafe operations and how to proceed
|
|
573
|
-
|
|
574
|
-
---
|
|
575
|
-
|
|
576
|
-
### ✅ MEDIUM PRIORITY - All User-Facing Features Completed
|
|
577
|
-
|
|
578
|
-
**Status:** All MEDIUM priority features have been fully implemented in v1.3.0.
|
|
579
|
-
|
|
580
|
-
#### 4. Trigger Detail Page (Section 8 - UI) - ✅ COMPLETED in v1.3.0
|
|
581
|
-
**Priority:** MEDIUM - Usability
|
|
582
|
-
|
|
583
|
-
**Status:** ✅ Fully implemented in v1.3.0
|
|
584
|
-
|
|
585
|
-
**Implementation:**
|
|
586
|
-
- ✅ Dedicated trigger detail route and controller action (`triggers#show`)
|
|
587
|
-
- ✅ Summary panel with all trigger metadata (name, table, version, status, source, environment, timestamps)
|
|
588
|
-
- ✅ SQL diff view (expected vs actual with syntax highlighting)
|
|
589
|
-
- ✅ Registry state display (comprehensive state including checksum, drift detection, manual override)
|
|
590
|
-
- ✅ Action buttons (Enable/Disable/Drop/Re-execute/Execute SQL capsule)
|
|
591
|
-
- ✅ Permission-aware, environment-aware, kill switch-aware button visibility
|
|
592
|
-
- ✅ Breadcrumb navigation
|
|
593
|
-
|
|
594
|
-
#### 5. UI Actions (Section 8) - ✅ COMPLETED in v1.3.0
|
|
595
|
-
**Priority:** MEDIUM - Usability
|
|
596
|
-
|
|
597
|
-
**Status:** ✅ Fully implemented in v1.3.0
|
|
598
|
-
|
|
599
|
-
**Implementation:**
|
|
600
|
-
- ✅ Enable/Disable buttons in dashboard, tables/show, and trigger detail pages
|
|
601
|
-
- ✅ Drop button with confirmation modal (Admin permission required)
|
|
602
|
-
- ✅ Re-execute button with drift diff display (Admin permission required)
|
|
603
|
-
- ✅ Execute SQL capsule button (Admin permission required)
|
|
604
|
-
|
|
605
|
-
**What Works:**
|
|
606
|
-
- ✅ Kill switch enforcement in UI (fully implemented - see Section 6)
|
|
607
|
-
- ✅ Migration actions (up/down/redo) with kill switch protection
|
|
608
|
-
- ✅ All action buttons with permission checks
|
|
609
|
-
- ✅ AJAX-based actions to avoid full page reloads
|
|
610
|
-
|
|
611
|
-
#### 6. Permissions Enforcement (Section 5) - ✅ COMPLETED in v1.3.0
|
|
612
|
-
**Priority:** MEDIUM - Security
|
|
613
|
-
|
|
614
|
-
**Status:** ✅ Fully enforced in v1.3.0
|
|
615
|
-
|
|
616
|
-
**Implementation:**
|
|
617
|
-
- ✅ Permission checking in controllers (all UI actions check permissions)
|
|
618
|
-
- ✅ Permission checking in UI (buttons show/hide based on role via `PermissionsHelper`)
|
|
619
|
-
- ✅ Permission checks in `TriggerRegistry#enable!` and `disable!` (Operator or Admin required)
|
|
620
|
-
- ✅ Permission checks in console APIs (all Registry methods check permissions)
|
|
621
|
-
- ✅ Permission checks in SQL Executor (Admin required)
|
|
622
|
-
- ✅ Actor context passing through all operations (actor tracked in audit logs)
|
|
623
|
-
|
|
624
|
-
**What Exists:**
|
|
625
|
-
- ✅ Permission structure (Viewer, Operator, Admin roles defined)
|
|
626
|
-
- ✅ Permission model classes (`PgSqlTriggers::Permissions::Checker`)
|
|
627
|
-
- ✅ Configurable `permission_checker` via configuration
|
|
628
|
-
- ✅ `PermissionError` exception class
|
|
629
|
-
|
|
630
|
-
---
|
|
631
|
-
|
|
632
|
-
### 🟢 LOW PRIORITY - Polish & Improvements
|
|
633
|
-
|
|
634
|
-
#### 7. Enhanced Logging & Audit Trail - ✅ COMPLETED in v1.3.0
|
|
635
|
-
**Priority:** LOW - Operational polish
|
|
636
|
-
|
|
637
|
-
**Status:** ✅ Fully implemented in v1.3.0
|
|
638
|
-
|
|
639
|
-
**Implementation:**
|
|
640
|
-
- ✅ Kill switch activation attempts logging (fully implemented)
|
|
641
|
-
- ✅ Kill switch overrides logging (fully implemented)
|
|
642
|
-
- ✅ Comprehensive audit trail table (`pg_sql_triggers_audit_log`) for all operations
|
|
643
|
-
- ✅ Audit logging for enable/disable/drop/re-execute/SQL capsule execution
|
|
644
|
-
- ✅ Complete state capture (before/after) for all operations
|
|
645
|
-
- ✅ Actor tracking for all operations
|
|
646
|
-
- ✅ Error message logging for failed operations
|
|
647
|
-
- ✅ Audit log UI with filtering, sorting, pagination, and CSV export
|
|
648
|
-
- ✅ Console API: `PgSqlTriggers::AuditLog.for_trigger(name)`
|
|
649
|
-
|
|
650
|
-
#### 8. Error Handling Consistency - ✅ COMPLETED in v1.3.0
|
|
651
|
-
**Priority:** LOW - Code quality
|
|
652
|
-
|
|
653
|
-
**Status:** ✅ Fully implemented in v1.3.0
|
|
654
|
-
|
|
655
|
-
**Implementation:**
|
|
656
|
-
- ✅ Comprehensive error hierarchy with base `Error` class and specialized error types
|
|
657
|
-
- ✅ Error classes: `PermissionError`, `KillSwitchError`, `DriftError`, `ValidationError`, `ExecutionError`, `UnsafeMigrationError`, `NotFoundError`
|
|
658
|
-
- ✅ Error codes for programmatic handling (e.g., `PERMISSION_DENIED`, `KILL_SWITCH_ACTIVE`, `DRIFT_DETECTED`)
|
|
659
|
-
- ✅ Standardized error messages with recovery suggestions
|
|
660
|
-
- ✅ Enhanced error display in UI with user-friendly formatting
|
|
661
|
-
- ✅ Context information included in all errors for better debugging
|
|
662
|
-
- ✅ Error handling helpers in `ApplicationController` for consistent error formatting
|
|
663
|
-
- ✅ Kill switch violations raise `KillSwitchError` (fully implemented)
|
|
664
|
-
- ✅ Permission violations raise `PermissionError` (fully implemented)
|
|
665
|
-
- ✅ Drift detection implemented (can be used for error handling)
|
|
666
|
-
- ✅ Consistent error handling across all operations
|
|
667
|
-
|
|
668
|
-
#### 9. Testing Coverage - ✅ COMPREHENSIVE
|
|
669
|
-
**Priority:** LOW - Quality assurance
|
|
670
|
-
|
|
671
|
-
**Status:** ✅ Comprehensive test coverage achieved (93.45% in v1.3.0)
|
|
672
|
-
|
|
673
|
-
**Implementation:**
|
|
674
|
-
- ✅ SQL capsules have comprehensive tests
|
|
675
|
-
- ✅ Kill switch has comprehensive tests (fully tested)
|
|
676
|
-
- ✅ Drift detection has comprehensive tests (fully tested)
|
|
677
|
-
- ✅ Permission enforcement has comprehensive tests
|
|
678
|
-
- ✅ Drop/re-execute flow has comprehensive tests
|
|
679
|
-
- ✅ UI controller tests (triggers, dashboard, SQL capsules, audit logs)
|
|
680
|
-
- ✅ Integration tests (full workflows)
|
|
681
|
-
- ✅ Error handling tests
|
|
682
|
-
|
|
683
|
-
#### 10. Documentation Updates - ✅ COMPLETED in v1.3.0
|
|
684
|
-
**Priority:** LOW - User experience
|
|
685
|
-
|
|
686
|
-
**Status:** ✅ Comprehensive documentation completed in v1.3.0
|
|
687
|
-
|
|
688
|
-
**Implementation:**
|
|
689
|
-
- ✅ README updated with all v1.3.0 features
|
|
690
|
-
- ✅ README includes SQL capsules documentation with examples
|
|
691
|
-
- ✅ README includes kill switch documentation with enforcement details (fully documented)
|
|
692
|
-
- ✅ Examples provided for SQL capsules
|
|
693
|
-
- ✅ Examples provided for permission configuration
|
|
694
|
-
- ✅ Drift detection fully documented
|
|
695
|
-
- ✅ New comprehensive guides:
|
|
696
|
-
- `docs/ui-guide.md` - Using the web UI
|
|
697
|
-
- `docs/permissions.md` - Configuring permissions
|
|
698
|
-
- `docs/audit-trail.md` - Viewing audit logs
|
|
699
|
-
- `docs/troubleshooting.md` - Common issues and solutions
|
|
700
|
-
- ✅ API reference updated with all new methods
|
|
701
|
-
|
|
702
|
-
#### 11. Implementation Status Summary
|
|
703
|
-
**Priority:** LOW - Status tracking
|
|
704
|
-
|
|
705
|
-
**All Features Completed:**
|
|
706
|
-
- ✅ **Permissions Model** - Fully enforced in UI/CLI/console (v1.3.0)
|
|
707
|
-
- ✅ **Kill Switch** - Fully implemented (see Section 6 for details)
|
|
708
|
-
- ✅ **Checksum** - Fully implemented with consistent field-concatenation algorithm across all creation paths
|
|
709
|
-
- ✅ **Drift Detection** - Fully implemented with all 6 drift states, comprehensive tests, and console APIs
|
|
710
|
-
- ✅ **Dashboard** - `installed_at` displayed with formatting in UI (v1.3.0)
|
|
711
|
-
- ✅ **Trigger Detail Page** - Dedicated route/page fully implemented (v1.3.0)
|
|
712
|
-
- ✅ **Enable/Disable UI** - UI buttons implemented with permission checks (v1.3.0)
|
|
713
|
-
- ✅ **SQL Capsules** - Fully implemented (v1.2.0)
|
|
714
|
-
- ✅ **Drop & Re-Execute Flow** - Fully implemented (v1.2.0, UI in v1.3.0)
|
|
715
|
-
- ✅ **Audit Logging** - Comprehensive audit trail with UI (v1.3.0)
|
|
716
|
-
- ✅ **Error Handling** - Consistent error hierarchy and handling (v1.3.0)
|
|
717
|
-
|
|
718
|
-
---
|
|
719
|
-
|
|
720
|
-
### 📝 Technical Notes
|
|
721
|
-
|
|
722
|
-
1. **Console API Naming:** ✅ Standardized - All console APIs follow consistent naming:
|
|
723
|
-
- Query methods: `list`, `enabled`, `disabled`, `for_table`, `diff`, `drifted`, `in_sync`, `unknown_triggers`, `dropped`
|
|
724
|
-
- Action methods: `enable`, `disable`, `drop`, `re_execute`
|
|
725
|
-
- All methods are fully documented with YARD documentation
|
|
726
|
-
|
|
727
|
-
2. **Code Organization:** ✅ Improved - Common controller concerns extracted:
|
|
728
|
-
- `KillSwitchProtection` - Handles kill switch checking and confirmation
|
|
729
|
-
- `PermissionChecking` - Handles permission checks and actor management
|
|
730
|
-
- `ErrorHandling` - Handles error formatting and flash messages
|
|
731
|
-
- All controllers inherit from `ApplicationController` which includes these concerns
|
|
732
|
-
|
|
733
|
-
3. **Service Object Patterns:** ✅ Standardized - All service objects follow consistent patterns:
|
|
734
|
-
- `Generator::Service` - Class methods for stateless operations, fully documented
|
|
735
|
-
- `SQL::Executor` - Class methods for stateless operations, fully documented
|
|
736
|
-
- All public methods have YARD documentation
|
|
737
|
-
|
|
738
|
-
4. **YARD Documentation:** ✅ Added - Comprehensive YARD documentation for:
|
|
739
|
-
- `PgSqlTriggers::Registry` module and all public methods
|
|
740
|
-
- `PgSqlTriggers::TriggerRegistry` model and all public methods
|
|
741
|
-
- `PgSqlTriggers::Generator::Service` and all public methods
|
|
742
|
-
- `PgSqlTriggers::SQL::Executor` and all public methods
|