dbwatcher 1.0.0 → 1.1.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 (95) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +81 -210
  3. data/app/assets/config/dbwatcher_manifest.js +15 -0
  4. data/app/assets/javascripts/dbwatcher/alpine_registrations.js +39 -0
  5. data/app/assets/javascripts/dbwatcher/auto_init.js +23 -0
  6. data/app/assets/javascripts/dbwatcher/components/base.js +141 -0
  7. data/app/assets/javascripts/dbwatcher/components/changes_table_hybrid.js +1008 -0
  8. data/app/assets/javascripts/dbwatcher/components/diagrams.js +449 -0
  9. data/app/assets/javascripts/dbwatcher/components/summary.js +234 -0
  10. data/app/assets/javascripts/dbwatcher/core/alpine_store.js +138 -0
  11. data/app/assets/javascripts/dbwatcher/core/api_client.js +162 -0
  12. data/app/assets/javascripts/dbwatcher/core/component_loader.js +70 -0
  13. data/app/assets/javascripts/dbwatcher/core/component_registry.js +94 -0
  14. data/app/assets/javascripts/dbwatcher/dbwatcher.js +120 -0
  15. data/app/assets/javascripts/dbwatcher/services/mermaid.js +315 -0
  16. data/app/assets/javascripts/dbwatcher/services/mermaid_service.js +199 -0
  17. data/app/assets/javascripts/dbwatcher/vendor/date-fns-browser.js +99 -0
  18. data/app/assets/javascripts/dbwatcher/vendor/lodash.min.js +140 -0
  19. data/app/assets/javascripts/dbwatcher/vendor/tabulator.min.js +3 -0
  20. data/app/assets/stylesheets/dbwatcher/application.css +423 -0
  21. data/app/assets/stylesheets/dbwatcher/application.scss +15 -0
  22. data/app/assets/stylesheets/dbwatcher/components/_badges.scss +38 -0
  23. data/app/assets/stylesheets/dbwatcher/components/_compact_table.scss +162 -0
  24. data/app/assets/stylesheets/dbwatcher/components/_diagrams.scss +51 -0
  25. data/app/assets/stylesheets/dbwatcher/components/_forms.scss +27 -0
  26. data/app/assets/stylesheets/dbwatcher/components/_navigation.scss +55 -0
  27. data/app/assets/stylesheets/dbwatcher/core/_base.scss +34 -0
  28. data/app/assets/stylesheets/dbwatcher/core/_variables.scss +47 -0
  29. data/app/assets/stylesheets/dbwatcher/vendor/tabulator.min.css +2 -0
  30. data/app/controllers/dbwatcher/api/v1/sessions_controller.rb +64 -0
  31. data/app/controllers/dbwatcher/base_controller.rb +8 -2
  32. data/app/controllers/dbwatcher/dashboard_controller.rb +8 -0
  33. data/app/controllers/dbwatcher/sessions_controller.rb +25 -10
  34. data/app/helpers/dbwatcher/component_helper.rb +29 -0
  35. data/app/helpers/dbwatcher/diagram_helper.rb +110 -0
  36. data/app/helpers/dbwatcher/session_helper.rb +3 -2
  37. data/app/views/dbwatcher/sessions/_changes_tab.html.erb +265 -0
  38. data/app/views/dbwatcher/sessions/_diagrams_tab.html.erb +166 -0
  39. data/app/views/dbwatcher/sessions/_session_header.html.erb +11 -0
  40. data/app/views/dbwatcher/sessions/_summary_tab.html.erb +88 -0
  41. data/app/views/dbwatcher/sessions/_tab_navigation.html.erb +12 -0
  42. data/app/views/dbwatcher/sessions/changes.html.erb +21 -0
  43. data/app/views/dbwatcher/sessions/components/changes/_filters.html.erb +44 -0
  44. data/app/views/dbwatcher/sessions/components/changes/_table_list.html.erb +96 -0
  45. data/app/views/dbwatcher/sessions/diagrams.html.erb +21 -0
  46. data/app/views/dbwatcher/sessions/index.html.erb +14 -10
  47. data/app/views/dbwatcher/sessions/shared/_layout.html.erb +8 -0
  48. data/app/views/dbwatcher/sessions/shared/_navigation.html.erb +35 -0
  49. data/app/views/dbwatcher/sessions/shared/_session_header.html.erb +25 -0
  50. data/app/views/dbwatcher/sessions/show.html.erb +3 -346
  51. data/app/views/dbwatcher/sessions/summary.html.erb +21 -0
  52. data/app/views/layouts/dbwatcher/application.html.erb +125 -247
  53. data/bin/compile_scss +49 -0
  54. data/config/routes.rb +26 -0
  55. data/lib/dbwatcher/configuration.rb +102 -8
  56. data/lib/dbwatcher/engine.rb +17 -7
  57. data/lib/dbwatcher/services/analyzers/session_data_processor.rb +98 -0
  58. data/lib/dbwatcher/services/analyzers/table_summary_builder.rb +202 -0
  59. data/lib/dbwatcher/services/api/base_api_service.rb +100 -0
  60. data/lib/dbwatcher/services/api/changes_data_service.rb +112 -0
  61. data/lib/dbwatcher/services/api/diagram_data_service.rb +145 -0
  62. data/lib/dbwatcher/services/api/summary_data_service.rb +158 -0
  63. data/lib/dbwatcher/services/base_service.rb +64 -0
  64. data/lib/dbwatcher/services/diagram_analyzers/base_analyzer.rb +162 -0
  65. data/lib/dbwatcher/services/diagram_analyzers/foreign_key_analyzer.rb +354 -0
  66. data/lib/dbwatcher/services/diagram_analyzers/inferred_relationship_analyzer.rb +502 -0
  67. data/lib/dbwatcher/services/diagram_analyzers/model_association_analyzer.rb +603 -0
  68. data/lib/dbwatcher/services/diagram_data/attribute.rb +154 -0
  69. data/lib/dbwatcher/services/diagram_data/dataset.rb +280 -0
  70. data/lib/dbwatcher/services/diagram_data/entity.rb +180 -0
  71. data/lib/dbwatcher/services/diagram_data/relationship.rb +188 -0
  72. data/lib/dbwatcher/services/diagram_data/relationship_params.rb +55 -0
  73. data/lib/dbwatcher/services/diagram_data.rb +65 -0
  74. data/lib/dbwatcher/services/diagram_error_handler.rb +239 -0
  75. data/lib/dbwatcher/services/diagram_generator.rb +154 -0
  76. data/lib/dbwatcher/services/diagram_strategies/base_diagram_strategy.rb +149 -0
  77. data/lib/dbwatcher/services/diagram_strategies/class_diagram_strategy.rb +49 -0
  78. data/lib/dbwatcher/services/diagram_strategies/erd_diagram_strategy.rb +52 -0
  79. data/lib/dbwatcher/services/diagram_strategies/flowchart_diagram_strategy.rb +52 -0
  80. data/lib/dbwatcher/services/diagram_system.rb +69 -0
  81. data/lib/dbwatcher/services/diagram_type_registry.rb +164 -0
  82. data/lib/dbwatcher/services/mermaid_syntax/base_builder.rb +127 -0
  83. data/lib/dbwatcher/services/mermaid_syntax/cardinality_mapper.rb +90 -0
  84. data/lib/dbwatcher/services/mermaid_syntax/class_diagram_builder.rb +140 -0
  85. data/lib/dbwatcher/services/mermaid_syntax/class_diagram_helper.rb +48 -0
  86. data/lib/dbwatcher/services/mermaid_syntax/erd_builder.rb +116 -0
  87. data/lib/dbwatcher/services/mermaid_syntax/flowchart_builder.rb +109 -0
  88. data/lib/dbwatcher/services/mermaid_syntax/sanitizer.rb +118 -0
  89. data/lib/dbwatcher/services/mermaid_syntax_builder.rb +155 -0
  90. data/lib/dbwatcher/storage/api/concerns/table_analyzer.rb +15 -128
  91. data/lib/dbwatcher/storage/api/session_api.rb +47 -0
  92. data/lib/dbwatcher/storage/base_storage.rb +7 -0
  93. data/lib/dbwatcher/version.rb +1 -1
  94. data/lib/dbwatcher.rb +58 -1
  95. metadata +94 -2
@@ -0,0 +1,155 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
4
+ require "digest"
5
+
6
+ module Dbwatcher
7
+ module Services
8
+ # Builder for generating validated Mermaid diagram syntax
9
+ #
10
+ # Provides methods for building different types of Mermaid diagrams with
11
+ # syntax validation, error checking, and consistent formatting.
12
+ #
13
+ # @example
14
+ # builder = MermaidSyntaxBuilder.new
15
+ # content = builder.build_erd_diagram_from_dataset(dataset)
16
+ # # => "erDiagram\n USERS ||--o{ ORDERS : user_id"
17
+ class MermaidSyntaxBuilder
18
+ # Custom error classes
19
+ class SyntaxValidationError < StandardError; end
20
+ class UnsupportedDiagramTypeError < StandardError; end
21
+
22
+ # Supported Mermaid diagram types
23
+ SUPPORTED_DIAGRAM_TYPES = %w[erDiagram classDiagram flowchart graph].freeze
24
+
25
+ # Maximum content length to prevent memory issues
26
+ MAX_CONTENT_LENGTH = 100_000
27
+
28
+ # Initialize builder
29
+ #
30
+ # @param config [Hash] builder configuration (optional)
31
+ # @option config [Logger] :logger logger instance
32
+ def initialize(config = {})
33
+ @config = config
34
+ @logger = config[:logger] || Rails.logger
35
+ end
36
+
37
+ # Build ERD diagram from dataset
38
+ #
39
+ # @param dataset [DiagramData::Dataset] dataset to render
40
+ # @param options [Hash] generation options
41
+ # @return [String] Mermaid ERD syntax
42
+ def build_erd_diagram_from_dataset(dataset, options = {})
43
+ @logger.debug "Building ERD diagram from dataset with #{dataset.entities.size} entities and " \
44
+ "#{dataset.relationships.size} relationships"
45
+
46
+ builder = MermaidSyntax::ErdBuilder.new(@config.merge(options))
47
+ builder.build_from_dataset(dataset)
48
+ end
49
+
50
+ # Build class diagram from dataset
51
+ #
52
+ # @param dataset [DiagramData::Dataset] dataset to render
53
+ # @param options [Hash] generation options
54
+ # @return [String] Mermaid class diagram syntax
55
+ def build_class_diagram_from_dataset(dataset, options = {})
56
+ @logger.debug "Building class diagram from dataset with #{dataset.entities.size} entities and " \
57
+ "#{dataset.relationships.size} relationships"
58
+
59
+ builder = MermaidSyntax::ClassDiagramBuilder.new(@config.merge(options))
60
+ builder.build_from_dataset(dataset)
61
+ end
62
+
63
+ # Build flowchart diagram from dataset
64
+ #
65
+ # @param dataset [DiagramData::Dataset] dataset to render
66
+ # @param options [Hash] generation options
67
+ # @return [String] Mermaid flowchart syntax
68
+ def build_flowchart_diagram_from_dataset(dataset, options = {})
69
+ @logger.debug "Building flowchart diagram from dataset with #{dataset.entities.size} entities and " \
70
+ "#{dataset.relationships.size} relationships"
71
+
72
+ builder = MermaidSyntax::FlowchartBuilder.new(@config.merge(options))
73
+ builder.build_from_dataset(dataset)
74
+ end
75
+
76
+ # Build empty ERD diagram with message
77
+ #
78
+ # @param message [String] message to display
79
+ # @return [String] Mermaid ERD syntax
80
+ def build_empty_erd(message)
81
+ builder = MermaidSyntax::ErdBuilder.new(@config)
82
+ builder.build_empty(message)
83
+ end
84
+
85
+ # Build empty flowchart diagram with message
86
+ #
87
+ # @param message [String] message to display
88
+ # @return [String] Mermaid flowchart syntax
89
+ def build_empty_flowchart(message)
90
+ builder = MermaidSyntax::FlowchartBuilder.new(@config)
91
+ builder.build_empty(message)
92
+ end
93
+
94
+ # Build empty class diagram with message
95
+ #
96
+ # @param message [String] message to display
97
+ # @return [String] Mermaid class diagram syntax
98
+ def build_empty_class_diagram(message)
99
+ builder = MermaidSyntax::ClassDiagramBuilder.new(@config)
100
+ builder.build_empty(message)
101
+ end
102
+
103
+ # Build empty diagram of specified type
104
+ #
105
+ # @param message [String] message to display
106
+ # @param diagram_type [String] type of diagram
107
+ # @return [String] Mermaid syntax
108
+ # @raise [UnsupportedDiagramTypeError] if type unsupported
109
+ def build_empty_diagram(message, diagram_type)
110
+ case diagram_type
111
+ when "erDiagram", "erd"
112
+ build_empty_erd(message)
113
+ when "classDiagram", "class"
114
+ build_empty_class_diagram(message)
115
+ when "flowchart", "graph"
116
+ build_empty_flowchart(message)
117
+ else
118
+ raise UnsupportedDiagramTypeError, "Unsupported diagram type: #{diagram_type}"
119
+ end
120
+ end
121
+
122
+ # Build ERD diagram with isolated tables
123
+ #
124
+ # @param entities [Array<Entity>] isolated table entities
125
+ # @param options [Hash] generation options
126
+ # @return [String] Mermaid ERD syntax
127
+ def build_erd_diagram_with_tables(entities, options = {})
128
+ @logger.debug "Building ERD diagram with #{entities.size} isolated tables"
129
+
130
+ dataset = Dbwatcher::Services::DiagramData::Dataset.new
131
+ entities.each { |entity| dataset.add_entity(entity) }
132
+
133
+ build_erd_diagram_from_dataset(dataset, options)
134
+ end
135
+
136
+ # Build flowchart diagram with isolated nodes
137
+ #
138
+ # @param entities [Array<Entity>] isolated node entities
139
+ # @param options [Hash] generation options
140
+ # @return [String] Mermaid flowchart syntax
141
+ def build_flowchart_with_nodes(entities, options = {})
142
+ @logger.debug "Building flowchart diagram with #{entities.size} isolated nodes"
143
+
144
+ dataset = Dbwatcher::Services::DiagramData::Dataset.new
145
+ entities.each { |entity| dataset.add_entity(entity) }
146
+
147
+ build_flowchart_diagram_from_dataset(dataset, options)
148
+ end
149
+
150
+ # For backward compatibility with legacy code
151
+ alias build_erd_diagram build_erd_diagram_from_dataset
152
+ alias build_flowchart_diagram build_flowchart_diagram_from_dataset
153
+ end
154
+ end
155
+ end
@@ -6,8 +6,8 @@ module Dbwatcher
6
6
  module Concerns
7
7
  # Provides reusable table analysis functionality for API classes
8
8
  #
9
- # This concern extracts common table analysis logic used by API classes
10
- # to avoid duplication and provide consistent table analysis capabilities.
9
+ # This concern now acts as a facade, delegating specific responsibilities
10
+ # to specialized service classes while maintaining backward compatibility.
11
11
  #
12
12
  # @example
13
13
  # class MyAPI < BaseAPI
@@ -23,148 +23,35 @@ module Dbwatcher
23
23
  # @param session [Session] session to analyze
24
24
  # @return [Hash] tables summary hash
25
25
  def build_tables_summary(session)
26
- tables = {}
27
- process_session_changes(session, tables)
28
- tables
26
+ # Delegate to new service while maintaining interface compatibility
27
+ Dbwatcher::Services::Analyzers::TableSummaryBuilder.call(session)
29
28
  end
30
29
 
31
- # Process all changes in a session
30
+ # Process all changes in a session (legacy method for backward compatibility)
32
31
  #
33
32
  # @param session [Session] session with changes
34
- # @param tables [Hash] tables hash to populate
33
+ # @param _tables [Hash] tables hash to populate (unused but kept for compatibility)
35
34
  # @return [void]
36
- def process_session_changes(session, tables)
37
- return unless session&.changes.respond_to?(:each)
38
-
39
- session.changes.each do |change|
40
- table_name = extract_table_name(change)
41
- next unless table_name
42
-
43
- initialize_table_data(tables, table_name)
44
- update_table_data(tables[table_name], change)
45
- update_sample_record(tables[table_name], change)
35
+ def process_session_changes(session, _tables)
36
+ # Use new service for processing but maintain yield interface
37
+ processor = Dbwatcher::Services::Analyzers::SessionDataProcessor.new(session)
38
+ processor.process_changes do |table_name, change, _|
39
+ yield(table_name, change) if block_given?
46
40
  end
47
41
  end
48
42
 
49
- # Extract table name from change data
43
+ # Legacy methods maintained for backward compatibility
44
+ # These now delegate to the new service classes
45
+
46
+ # Extract table name from change data (legacy compatibility)
50
47
  #
51
48
  # @param change [Hash] change data
52
49
  # @return [String, nil] table name or nil
53
50
  def extract_table_name(change)
54
51
  return nil unless change.is_a?(Hash)
55
52
 
56
- # Only use symbols since data is normalized
57
53
  change[:table_name]
58
54
  end
59
-
60
- # Initialize table data structure
61
- #
62
- # @param tables [Hash] tables hash
63
- # @param table_name [String] table name
64
- # @return [void]
65
- def initialize_table_data(tables, table_name)
66
- tables[table_name] ||= {
67
- name: table_name,
68
- operations: { "INSERT" => 0, "UPDATE" => 0, "DELETE" => 0 },
69
- changes: [],
70
- sample_record: nil,
71
- records: {},
72
- relationships: []
73
- }
74
- end
75
-
76
- # Update table data with change information
77
- #
78
- # @param table_data [Hash] table data hash
79
- # @param change [Hash] change data
80
- # @return [void]
81
- def update_table_data(table_data, change)
82
- # Count operations
83
- operation = extract_operation(change)
84
- table_data[:operations][operation] ||= 0
85
- table_data[:operations][operation] += 1
86
-
87
- # Add change to the list
88
- table_data[:changes] << change
89
- end
90
-
91
- # Update sample record if not already set
92
- #
93
- # @param table_data [Hash] table data hash
94
- # @param change [Hash] change data
95
- # @return [void]
96
- def update_sample_record(table_data, change)
97
- return unless table_data[:sample_record].nil?
98
-
99
- snapshot = extract_record_snapshot(change)
100
- table_data[:sample_record] = snapshot if snapshot
101
- end
102
-
103
- # Update record history for analysis
104
- #
105
- # @param table_data [Hash] table data hash
106
- # @param change [Hash] change data
107
- # @return [void]
108
- def update_record_history(table_data, change)
109
- record_id = extract_record_id(change)
110
- return unless record_id
111
-
112
- table_data[:records][record_id] ||= []
113
- table_data[:records][record_id] << {
114
- operation: extract_operation(change),
115
- timestamp: extract_timestamp(change),
116
- changes: extract_field_changes(change)
117
- }
118
- end
119
-
120
- private
121
-
122
- # Extract operation from change data
123
- #
124
- # @param change [Hash] change data
125
- # @return [String] operation string
126
- def extract_operation(change)
127
- # Only use symbols since data is normalized
128
- operation = change[:operation] || "UNKNOWN"
129
- operation.to_s.upcase
130
- end
131
-
132
- # Extract record snapshot from change data
133
- #
134
- # @param change [Hash] change data
135
- # @return [Hash, nil] record snapshot or nil
136
- def extract_record_snapshot(change)
137
- # Only use symbols since data is normalized
138
- change[:record_snapshot]
139
- end
140
-
141
- # Extract record ID from change data
142
- #
143
- # @param change [Hash] change data
144
- # @return [String, nil] record ID or nil
145
- def extract_record_id(change)
146
- # Only use symbols since data is normalized
147
- id = change[:record_id]
148
- id&.to_s
149
- end
150
-
151
- # Extract timestamp from change data
152
- #
153
- # @param change [Hash] change data
154
- # @return [String, nil] timestamp string or nil
155
- def extract_timestamp(change)
156
- # Only use symbols since data is normalized
157
- change[:timestamp]
158
- end
159
-
160
- # Extract field changes from change data
161
- #
162
- # @param change [Hash] change data
163
- # @return [Hash] field changes hash
164
- def extract_field_changes(change)
165
- # Only use symbols since data is normalized
166
- change[:changes] || {}
167
- end
168
55
  end
169
56
  end
170
57
  end
@@ -91,6 +91,42 @@ module Dbwatcher
91
91
  .first(limit)
92
92
  end
93
93
 
94
+ # Get comprehensive session analysis including tables and relationships
95
+ #
96
+ # @param session_id [String] session identifier
97
+ # @return [Hash] session analysis data
98
+ def summary(session_id)
99
+ session = find(session_id)
100
+ return { error: "Session not found" } unless session
101
+
102
+ {
103
+ tables_summary: tables_summary(session_id),
104
+ total_changes: session.changes&.count || 0,
105
+ session_metadata: extract_session_metadata(session)
106
+ }
107
+ end
108
+
109
+ # Get tables summary for a session
110
+ #
111
+ # @param session_id [String] session identifier
112
+ # @return [Hash] tables summary
113
+ def tables_summary(session_id)
114
+ session = find(session_id)
115
+ return { error: "Session not found" } unless session
116
+
117
+ analyzer = Dbwatcher::Services::Analyzers::TableSummaryBuilder.new(session)
118
+ analyzer.call
119
+ end
120
+
121
+ # Generate diagram data for a session
122
+ #
123
+ # @param session_id [String] session identifier
124
+ # @param diagram_type [String] type of diagram to generate
125
+ # @return [Hash] diagram data
126
+ def diagram_data(session_id, diagram_type = "database_tables")
127
+ Dbwatcher::Services::DiagramSystem.generate(session_id, diagram_type)
128
+ end
129
+
94
130
  private
95
131
 
96
132
  def apply_filters(sessions)
@@ -128,6 +164,17 @@ module Dbwatcher
128
164
  session&.changes&.any?
129
165
  end
130
166
  end
167
+
168
+ # Extract session metadata for analysis
169
+ #
170
+ # @param session [Session] session object
171
+ # @return [Hash] metadata hash
172
+ def extract_session_metadata(session)
173
+ {
174
+ id: session.id,
175
+ changes_count: session.changes&.count || 0
176
+ }
177
+ end
131
178
  end
132
179
  end
133
180
  end
@@ -47,8 +47,15 @@ module Dbwatcher
47
47
  # instance, and initializes timestamps.
48
48
  #
49
49
  # @param storage_path [String, nil] custom storage path (optional)
50
+ # @raise [StorageError] if storage_path is nil or empty
50
51
  def initialize(storage_path = nil)
51
52
  @storage_path = storage_path || Dbwatcher.configuration.storage_path
53
+
54
+ # Ensure storage path is valid
55
+ if @storage_path.nil? || @storage_path.to_s.strip.empty?
56
+ raise StorageError, "Storage path cannot be nil or empty. Please configure a valid storage path."
57
+ end
58
+
52
59
  @file_manager = FileManager.new(@storage_path)
53
60
  initialize_timestamps
54
61
  ensure_storage_directory
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dbwatcher
4
- VERSION = "1.0.0"
4
+ VERSION = "1.1.1"
5
5
  end
data/lib/dbwatcher.rb CHANGED
@@ -5,17 +5,74 @@ require "fileutils"
5
5
  require "securerandom"
6
6
  require "singleton"
7
7
  require "logger"
8
+
9
+ # Core components
8
10
  require_relative "dbwatcher/version"
9
11
  require_relative "dbwatcher/configuration"
10
12
  require_relative "dbwatcher/logging"
11
- require_relative "dbwatcher/tracker"
13
+
14
+ # Storage layer
12
15
  require_relative "dbwatcher/storage"
16
+
17
+ # Tracking and SQL monitoring
18
+ require_relative "dbwatcher/tracker"
13
19
  require_relative "dbwatcher/sql_logger"
14
20
  require_relative "dbwatcher/model_extension"
15
21
  require_relative "dbwatcher/middleware"
22
+
23
+ # Base services
24
+ require_relative "dbwatcher/services/base_service"
25
+
26
+ # Core services
16
27
  require_relative "dbwatcher/services/table_statistics_collector"
17
28
  require_relative "dbwatcher/services/dashboard_data_aggregator"
18
29
  require_relative "dbwatcher/services/query_filter_processor"
30
+
31
+ # General analyzers
32
+ require_relative "dbwatcher/services/analyzers/session_data_processor"
33
+ require_relative "dbwatcher/services/analyzers/table_summary_builder"
34
+
35
+ # Diagram data models
36
+ require_relative "dbwatcher/services/diagram_data/attribute"
37
+ require_relative "dbwatcher/services/diagram_data/entity"
38
+ require_relative "dbwatcher/services/diagram_data/relationship"
39
+ require_relative "dbwatcher/services/diagram_data/dataset"
40
+ require_relative "dbwatcher/services/diagram_data"
41
+
42
+ # Diagram analyzers
43
+ require_relative "dbwatcher/services/diagram_analyzers/base_analyzer"
44
+ require_relative "dbwatcher/services/diagram_analyzers/foreign_key_analyzer"
45
+ require_relative "dbwatcher/services/diagram_analyzers/inferred_relationship_analyzer"
46
+ require_relative "dbwatcher/services/diagram_analyzers/model_association_analyzer"
47
+
48
+ # Mermaid syntax builders
49
+ require_relative "dbwatcher/services/mermaid_syntax/base_builder"
50
+ require_relative "dbwatcher/services/mermaid_syntax/sanitizer"
51
+ require_relative "dbwatcher/services/mermaid_syntax/cardinality_mapper"
52
+ require_relative "dbwatcher/services/mermaid_syntax/erd_builder"
53
+ require_relative "dbwatcher/services/mermaid_syntax/class_diagram_builder"
54
+ require_relative "dbwatcher/services/mermaid_syntax/flowchart_builder"
55
+ require_relative "dbwatcher/services/mermaid_syntax_builder"
56
+
57
+ # Diagram strategies
58
+ require_relative "dbwatcher/services/diagram_strategies/base_diagram_strategy"
59
+ require_relative "dbwatcher/services/diagram_strategies/erd_diagram_strategy"
60
+ require_relative "dbwatcher/services/diagram_strategies/class_diagram_strategy"
61
+ require_relative "dbwatcher/services/diagram_strategies/flowchart_diagram_strategy"
62
+
63
+ # Diagram system
64
+ require_relative "dbwatcher/services/diagram_error_handler"
65
+ require_relative "dbwatcher/services/diagram_type_registry"
66
+ require_relative "dbwatcher/services/diagram_generator"
67
+ require_relative "dbwatcher/services/diagram_system"
68
+
69
+ # API services
70
+ require_relative "dbwatcher/services/api/base_api_service"
71
+ require_relative "dbwatcher/services/api/changes_data_service"
72
+ require_relative "dbwatcher/services/api/summary_data_service"
73
+ require_relative "dbwatcher/services/api/diagram_data_service"
74
+
75
+ # Rails engine
19
76
  require_relative "dbwatcher/engine" if defined?(Rails)
20
77
 
21
78
  module Dbwatcher
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dbwatcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Huy Nguyen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-06-15 00:00:00.000000000 Z
11
+ date: 2025-07-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '6.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: sassc
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '2.4'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '2.4'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: selenium-webdriver
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -141,6 +155,7 @@ description: DB Watcher helps developers debug Rails applications by tracking al
141
155
  email:
142
156
  - patrick204nqh@gmail.com
143
157
  executables:
158
+ - compile_scss
144
159
  - console
145
160
  - release
146
161
  - setup
@@ -149,18 +164,61 @@ extra_rdoc_files: []
149
164
  files:
150
165
  - README.md
151
166
  - Rakefile
167
+ - app/assets/config/dbwatcher_manifest.js
168
+ - app/assets/javascripts/dbwatcher/alpine_registrations.js
169
+ - app/assets/javascripts/dbwatcher/auto_init.js
170
+ - app/assets/javascripts/dbwatcher/components/base.js
171
+ - app/assets/javascripts/dbwatcher/components/changes_table_hybrid.js
172
+ - app/assets/javascripts/dbwatcher/components/diagrams.js
173
+ - app/assets/javascripts/dbwatcher/components/summary.js
174
+ - app/assets/javascripts/dbwatcher/core/alpine_store.js
175
+ - app/assets/javascripts/dbwatcher/core/api_client.js
176
+ - app/assets/javascripts/dbwatcher/core/component_loader.js
177
+ - app/assets/javascripts/dbwatcher/core/component_registry.js
178
+ - app/assets/javascripts/dbwatcher/dbwatcher.js
179
+ - app/assets/javascripts/dbwatcher/services/mermaid.js
180
+ - app/assets/javascripts/dbwatcher/services/mermaid_service.js
181
+ - app/assets/javascripts/dbwatcher/vendor/date-fns-browser.js
182
+ - app/assets/javascripts/dbwatcher/vendor/lodash.min.js
183
+ - app/assets/javascripts/dbwatcher/vendor/tabulator.min.js
184
+ - app/assets/stylesheets/dbwatcher/application.css
185
+ - app/assets/stylesheets/dbwatcher/application.scss
186
+ - app/assets/stylesheets/dbwatcher/components/_badges.scss
187
+ - app/assets/stylesheets/dbwatcher/components/_compact_table.scss
188
+ - app/assets/stylesheets/dbwatcher/components/_diagrams.scss
189
+ - app/assets/stylesheets/dbwatcher/components/_forms.scss
190
+ - app/assets/stylesheets/dbwatcher/components/_navigation.scss
191
+ - app/assets/stylesheets/dbwatcher/core/_base.scss
192
+ - app/assets/stylesheets/dbwatcher/core/_variables.scss
193
+ - app/assets/stylesheets/dbwatcher/vendor/tabulator.min.css
194
+ - app/controllers/dbwatcher/api/v1/sessions_controller.rb
152
195
  - app/controllers/dbwatcher/base_controller.rb
153
196
  - app/controllers/dbwatcher/dashboard_controller.rb
154
197
  - app/controllers/dbwatcher/queries_controller.rb
155
198
  - app/controllers/dbwatcher/sessions_controller.rb
156
199
  - app/controllers/dbwatcher/tables_controller.rb
157
200
  - app/helpers/dbwatcher/application_helper.rb
201
+ - app/helpers/dbwatcher/component_helper.rb
202
+ - app/helpers/dbwatcher/diagram_helper.rb
158
203
  - app/helpers/dbwatcher/formatting_helper.rb
159
204
  - app/helpers/dbwatcher/session_helper.rb
160
205
  - app/views/dbwatcher/dashboard/index.html.erb
161
206
  - app/views/dbwatcher/queries/index.html.erb
207
+ - app/views/dbwatcher/sessions/_changes_tab.html.erb
208
+ - app/views/dbwatcher/sessions/_diagrams_tab.html.erb
209
+ - app/views/dbwatcher/sessions/_session_header.html.erb
210
+ - app/views/dbwatcher/sessions/_summary_tab.html.erb
211
+ - app/views/dbwatcher/sessions/_tab_navigation.html.erb
212
+ - app/views/dbwatcher/sessions/changes.html.erb
213
+ - app/views/dbwatcher/sessions/components/changes/_filters.html.erb
214
+ - app/views/dbwatcher/sessions/components/changes/_table_list.html.erb
215
+ - app/views/dbwatcher/sessions/diagrams.html.erb
162
216
  - app/views/dbwatcher/sessions/index.html.erb
217
+ - app/views/dbwatcher/sessions/shared/_layout.html.erb
218
+ - app/views/dbwatcher/sessions/shared/_navigation.html.erb
219
+ - app/views/dbwatcher/sessions/shared/_session_header.html.erb
163
220
  - app/views/dbwatcher/sessions/show.html.erb
221
+ - app/views/dbwatcher/sessions/summary.html.erb
164
222
  - app/views/dbwatcher/shared/_badge.html.erb
165
223
  - app/views/dbwatcher/shared/_data_table.html.erb
166
224
  - app/views/dbwatcher/shared/_header.html.erb
@@ -172,6 +230,7 @@ files:
172
230
  - app/views/dbwatcher/tables/index.html.erb
173
231
  - app/views/dbwatcher/tables/show.html.erb
174
232
  - app/views/layouts/dbwatcher/application.html.erb
233
+ - bin/compile_scss
175
234
  - bin/console
176
235
  - bin/release
177
236
  - bin/setup
@@ -182,7 +241,40 @@ files:
182
241
  - lib/dbwatcher/logging.rb
183
242
  - lib/dbwatcher/middleware.rb
184
243
  - lib/dbwatcher/model_extension.rb
244
+ - lib/dbwatcher/services/analyzers/session_data_processor.rb
245
+ - lib/dbwatcher/services/analyzers/table_summary_builder.rb
246
+ - lib/dbwatcher/services/api/base_api_service.rb
247
+ - lib/dbwatcher/services/api/changes_data_service.rb
248
+ - lib/dbwatcher/services/api/diagram_data_service.rb
249
+ - lib/dbwatcher/services/api/summary_data_service.rb
250
+ - lib/dbwatcher/services/base_service.rb
185
251
  - lib/dbwatcher/services/dashboard_data_aggregator.rb
252
+ - lib/dbwatcher/services/diagram_analyzers/base_analyzer.rb
253
+ - lib/dbwatcher/services/diagram_analyzers/foreign_key_analyzer.rb
254
+ - lib/dbwatcher/services/diagram_analyzers/inferred_relationship_analyzer.rb
255
+ - lib/dbwatcher/services/diagram_analyzers/model_association_analyzer.rb
256
+ - lib/dbwatcher/services/diagram_data.rb
257
+ - lib/dbwatcher/services/diagram_data/attribute.rb
258
+ - lib/dbwatcher/services/diagram_data/dataset.rb
259
+ - lib/dbwatcher/services/diagram_data/entity.rb
260
+ - lib/dbwatcher/services/diagram_data/relationship.rb
261
+ - lib/dbwatcher/services/diagram_data/relationship_params.rb
262
+ - lib/dbwatcher/services/diagram_error_handler.rb
263
+ - lib/dbwatcher/services/diagram_generator.rb
264
+ - lib/dbwatcher/services/diagram_strategies/base_diagram_strategy.rb
265
+ - lib/dbwatcher/services/diagram_strategies/class_diagram_strategy.rb
266
+ - lib/dbwatcher/services/diagram_strategies/erd_diagram_strategy.rb
267
+ - lib/dbwatcher/services/diagram_strategies/flowchart_diagram_strategy.rb
268
+ - lib/dbwatcher/services/diagram_system.rb
269
+ - lib/dbwatcher/services/diagram_type_registry.rb
270
+ - lib/dbwatcher/services/mermaid_syntax/base_builder.rb
271
+ - lib/dbwatcher/services/mermaid_syntax/cardinality_mapper.rb
272
+ - lib/dbwatcher/services/mermaid_syntax/class_diagram_builder.rb
273
+ - lib/dbwatcher/services/mermaid_syntax/class_diagram_helper.rb
274
+ - lib/dbwatcher/services/mermaid_syntax/erd_builder.rb
275
+ - lib/dbwatcher/services/mermaid_syntax/flowchart_builder.rb
276
+ - lib/dbwatcher/services/mermaid_syntax/sanitizer.rb
277
+ - lib/dbwatcher/services/mermaid_syntax_builder.rb
186
278
  - lib/dbwatcher/services/query_filter_processor.rb
187
279
  - lib/dbwatcher/services/table_statistics_collector.rb
188
280
  - lib/dbwatcher/sql_logger.rb