flutter 0.1.0.pre.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +7 -0
  2. data/.overcommit.yml +8 -0
  3. data/.rubocop.yml +10 -0
  4. data/CHANGELOG.md +6 -0
  5. data/CODE_OF_CONDUCT.md +84 -0
  6. data/Gemfile +35 -0
  7. data/Guardfile +9 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +134 -0
  10. data/Rakefile +24 -0
  11. data/TODO.md +30 -0
  12. data/integration_tests/minitest/grape_app/.gitignore +67 -0
  13. data/integration_tests/minitest/grape_app/.ruby-version +1 -0
  14. data/integration_tests/minitest/grape_app/Gemfile +17 -0
  15. data/integration_tests/minitest/grape_app/Gemfile.lock +89 -0
  16. data/integration_tests/minitest/grape_app/README.md +2 -0
  17. data/integration_tests/minitest/grape_app/Rakefile +9 -0
  18. data/integration_tests/minitest/grape_app/api/api.rb +34 -0
  19. data/integration_tests/minitest/grape_app/api/routes/api_helpers.rb +12 -0
  20. data/integration_tests/minitest/grape_app/api/routes/change_request/api.rb +69 -0
  21. data/integration_tests/minitest/grape_app/api/routes/change_request/response_entity.rb +18 -0
  22. data/integration_tests/minitest/grape_app/api/routes/event/api.rb +121 -0
  23. data/integration_tests/minitest/grape_app/api/routes/event/response_entity.rb +41 -0
  24. data/integration_tests/minitest/grape_app/api/routes/project/api.rb +59 -0
  25. data/integration_tests/minitest/grape_app/api/routes/project/response_entity.rb +13 -0
  26. data/integration_tests/minitest/grape_app/api/routes/property/api.rb +78 -0
  27. data/integration_tests/minitest/grape_app/api/routes/property/response_entity.rb +31 -0
  28. data/integration_tests/minitest/grape_app/api/routes/trackable_object/api.rb +64 -0
  29. data/integration_tests/minitest/grape_app/api/routes/trackable_object/response_entity.rb +24 -0
  30. data/integration_tests/minitest/grape_app/api/routes/tracking_spec/api.rb +88 -0
  31. data/integration_tests/minitest/grape_app/api/routes/tracking_spec/response_entity.rb +17 -0
  32. data/integration_tests/minitest/grape_app/api/routes/tracking_spec/spec_response.rb +19 -0
  33. data/integration_tests/minitest/grape_app/api/routes/user/api.rb +22 -0
  34. data/integration_tests/minitest/grape_app/api/routes/user/response_entity.rb +12 -0
  35. data/integration_tests/minitest/grape_app/app/app.rb +30 -0
  36. data/integration_tests/minitest/grape_app/app/change_request/endpoint.rb +24 -0
  37. data/integration_tests/minitest/grape_app/app/change_request/generate_system_changes.rb +25 -0
  38. data/integration_tests/minitest/grape_app/app/change_request/service.rb +79 -0
  39. data/integration_tests/minitest/grape_app/app/event/endpoint.rb +78 -0
  40. data/integration_tests/minitest/grape_app/app/event/service.rb +68 -0
  41. data/integration_tests/minitest/grape_app/app/event/validator.rb +108 -0
  42. data/integration_tests/minitest/grape_app/app/project/endpoint.rb +24 -0
  43. data/integration_tests/minitest/grape_app/app/project/service.rb +42 -0
  44. data/integration_tests/minitest/grape_app/app/property/endpoint.rb +39 -0
  45. data/integration_tests/minitest/grape_app/app/property/service.rb +56 -0
  46. data/integration_tests/minitest/grape_app/app/trackable_object/endpoint.rb +38 -0
  47. data/integration_tests/minitest/grape_app/app/trackable_object/service.rb +49 -0
  48. data/integration_tests/minitest/grape_app/app/trackable_object/validator.rb +40 -0
  49. data/integration_tests/minitest/grape_app/app/tracking_spec/endpoint.rb +58 -0
  50. data/integration_tests/minitest/grape_app/app/tracking_spec/expand_tracking_spec_events.rb +91 -0
  51. data/integration_tests/minitest/grape_app/app/tracking_spec/service.rb +51 -0
  52. data/integration_tests/minitest/grape_app/app/tracking_spec/validator.rb +61 -0
  53. data/integration_tests/minitest/grape_app/app/utils/errors/api_exceptions.rb +10 -0
  54. data/integration_tests/minitest/grape_app/app/utils/errors/service_exceptions.rb +12 -0
  55. data/integration_tests/minitest/grape_app/app/versioned_entity/entity.rb +110 -0
  56. data/integration_tests/minitest/grape_app/app/versioned_entity/service.rb +47 -0
  57. data/integration_tests/minitest/grape_app/app/versioned_entity/validator.rb +61 -0
  58. data/integration_tests/minitest/grape_app/app/versioned_entity_snapshot/entity.rb +32 -0
  59. data/integration_tests/minitest/grape_app/config/boot.rb +9 -0
  60. data/integration_tests/minitest/grape_app/config.ru +3 -0
  61. data/integration_tests/minitest/grape_app/db/proto/change_request.rb +10 -0
  62. data/integration_tests/minitest/grape_app/db/proto/common/doc.rb +86 -0
  63. data/integration_tests/minitest/grape_app/db/proto/event.rb +10 -0
  64. data/integration_tests/minitest/grape_app/db/proto/event_snapshot.rb +10 -0
  65. data/integration_tests/minitest/grape_app/db/proto/project.rb +21 -0
  66. data/integration_tests/minitest/grape_app/db/proto/property.rb +10 -0
  67. data/integration_tests/minitest/grape_app/db/proto/property_snapshot.rb +10 -0
  68. data/integration_tests/minitest/grape_app/db/proto/trackable_object.rb +10 -0
  69. data/integration_tests/minitest/grape_app/db/proto/trackable_object_snapshot.rb +10 -0
  70. data/integration_tests/minitest/grape_app/db/proto/tracking_spec.rb +10 -0
  71. data/integration_tests/minitest/grape_app/test/api/functional/event_test.rb +186 -0
  72. data/integration_tests/minitest/grape_app/test/api/functional/property_test.rb +197 -0
  73. data/integration_tests/minitest/grape_app/test/api/functional/trackable_object_test.rb +134 -0
  74. data/integration_tests/minitest/grape_app/test/api/functional/tracking_spec_test.rb +56 -0
  75. data/integration_tests/minitest/grape_app/test/api/functional/user_test.rb +24 -0
  76. data/integration_tests/minitest/grape_app/test/api/functional/versioned_entity_helper.rb +157 -0
  77. data/integration_tests/minitest/grape_app/test/fixtures/change_requests.rb +83 -0
  78. data/integration_tests/minitest/grape_app/test/fixtures/event_snapshots.rb +105 -0
  79. data/integration_tests/minitest/grape_app/test/fixtures/events.rb +58 -0
  80. data/integration_tests/minitest/grape_app/test/fixtures/properties.rb +66 -0
  81. data/integration_tests/minitest/grape_app/test/fixtures/property_snapshots.rb +124 -0
  82. data/integration_tests/minitest/grape_app/test/fixtures/sample_tracking_spec.json +125 -0
  83. data/integration_tests/minitest/grape_app/test/fixtures/trackable_objects.rb +58 -0
  84. data/integration_tests/minitest/grape_app/test/fixtures/trackable_objects_snapshots.rb +61 -0
  85. data/integration_tests/minitest/grape_app/test/fixtures/tracking_specs.rb +22 -0
  86. data/integration_tests/minitest/grape_app/test/test_helper.rb +15 -0
  87. data/lib/flutter/config.rb +24 -0
  88. data/lib/flutter/minitest.rb +83 -0
  89. data/lib/flutter/parser.rb +82 -0
  90. data/lib/flutter/persistence.rb +152 -0
  91. data/lib/flutter/rspec.rb +66 -0
  92. data/lib/flutter/tracker.rb +133 -0
  93. data/lib/flutter/version.rb +5 -0
  94. data/lib/flutter.rb +12 -0
  95. data/lib/minitest/flutter_plugin.rb +16 -0
  96. data/sig/flutter.rbs +4 -0
  97. metadata +187 -0
@@ -0,0 +1,49 @@
1
+ require_relative '../../app/versioned_entity/service'
2
+ require_relative 'validator'
3
+ module Skee
4
+ module App
5
+ module TrackableObject
6
+ class Service < Skee::App::VersionedEntityService
7
+ def self.entity
8
+ :trackable_object
9
+ end
10
+
11
+ def self.create_fields_keys
12
+ %i(
13
+ change_request_id
14
+ previous_snapshot_id
15
+ is_removed
16
+ name
17
+ property_ids
18
+ )
19
+ end
20
+
21
+ def self.update_fields_keys
22
+ %i(
23
+ change_request_id
24
+ is_removed
25
+ id
26
+ name
27
+ property_ids
28
+ )
29
+ end
30
+
31
+ def self.add_property(params)
32
+ Skee::App::TrackableObject::Validator.new(params).
33
+ validate_add_property
34
+ trackable_object = get(id: params[:id])
35
+ trackable_object_property_ids = trackable_object.versioned_entity_snapshot.property_ids
36
+ property_id = params[:property_id]
37
+
38
+ return if trackable_object_property_ids.include?(property_id)
39
+ update_property_ids = trackable_object_property_ids + [property_id]
40
+ update(
41
+ id: params[:id],
42
+ property_ids: update_property_ids,
43
+ change_request_id: params[:change_request_id]
44
+ )
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,40 @@
1
+ require_relative '../../app/change_request/service'
2
+ require_relative '../../app/tracking_spec/service'
3
+ module Skee
4
+ module App
5
+ module TrackableObject
6
+ class Validator
7
+ def initialize(params)
8
+ @params = params
9
+ end
10
+
11
+ ERRORS = Utils::Errors
12
+
13
+ def validate_add_property
14
+ validate_property_exists(@params[:property_id])
15
+ end
16
+
17
+ def validate_remove_property
18
+ validate_property_exists(@params[:property_id])
19
+ validate_property_belongs_to_trackable_object(@params[:property_id], @params[:id])
20
+ end
21
+
22
+ private
23
+
24
+ def validate_property_exists(property_id)
25
+ property_instance = Skee::App::DB_MAPPING_ENTITY[:property].find(property_id)
26
+ raise ERRORS::RecordNotFoundException.new('Resource not found') unless property_instance
27
+ end
28
+
29
+ def validate_property_belongs_to_trackable_object(property_id, trackable_object_id)
30
+ return if trackable_object(trackable_object_id).versioned_entity_snapshot.property_ids.include?(property_id)
31
+ raise ERRORS::NotAllowedToUpdate.new('Trackable object does not contain property.')
32
+ end
33
+
34
+ def trackable_object(trackable_object_id)
35
+ @trackable_object ||= Skee::App::TrackableObject::Service.get(id: trackable_object_id)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,58 @@
1
+ require_relative './service'
2
+ require_relative './validator'
3
+ require_relative './expand_tracking_spec_events'
4
+
5
+ module Skee::App::TrackingSpec
6
+ class Endpoint
7
+ ERRORS = Skee::App::Utils::Errors
8
+
9
+ def self.list
10
+ Service.list
11
+ end
12
+
13
+ def self.get(params)
14
+ Service.get(params)
15
+ end
16
+
17
+ def self.full_spec(params)
18
+ Service.full_spec(params)
19
+ end
20
+
21
+ def self.create(params)
22
+ Service.create(params)
23
+ rescue ERRORS::RecordNotFoundException,
24
+ ERRORS::NotAllowedToUpdate => e
25
+ raise ERRORS::ValidationError.new(e.message)
26
+ end
27
+
28
+ def self.update(params)
29
+ Service.update(params)
30
+ rescue ERRORS::RecordNotFoundException,
31
+ ERRORS::NotAllowedToUpdate => e
32
+ raise ERRORS::ValidationError.new(e.message)
33
+ end
34
+
35
+ def self.delete(params)
36
+ Service.delete(params)
37
+ rescue ERRORS::RecordNotFoundException,
38
+ ERRORS::NotAllowedToUpdate => e
39
+ raise ERRORS::ValidationError.new(e.message)
40
+ end
41
+
42
+ def self.expand(params)
43
+ Skee::App::TrackingSpec::Validator.new(params).validate_expand_params
44
+ tracking_spec = Service.get(params)
45
+ expanded_events = ExpandTrackingSpecEvents.new(tracking_spec, params[:change_request_id]).perform
46
+ OpenStruct.new(
47
+ id: tracking_spec.id,
48
+ identifier: tracking_spec.identifier,
49
+ version: tracking_spec.version,
50
+ project_id: tracking_spec.project_id,
51
+ status: tracking_spec.status,
52
+ events: expanded_events
53
+ )
54
+ rescue ERRORS::RecordNotFoundException => e
55
+ raise ERRORS::ValidationError.new(e.message)
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,91 @@
1
+ require_relative '../../app/event/service'
2
+ require_relative '../../app/property/service'
3
+
4
+ module Skee::App::TrackingSpec
5
+ class ExpandTrackingSpecEvents
6
+ def initialize(tracking_spec, change_request_id)
7
+ @tracking_spec = tracking_spec
8
+ @change_request_id = change_request_id
9
+ end
10
+
11
+ def perform
12
+ expand_events
13
+ end
14
+
15
+ private
16
+
17
+ def event_snapshots
18
+ @tracking_spec.events.map do |event_id|
19
+ Skee::App::Event::Service.get(
20
+ id: event_id,
21
+ change_request_id: @change_request_id
22
+ ).versioned_entity_snapshot
23
+ end
24
+ end
25
+
26
+ def expand_events
27
+ event_snapshots.map do |snapshot|
28
+ event_payload = snapshot.payload
29
+ expanded_payload = event_payload.map do |key, value|
30
+ expanded_value = if value[:reference_entity_type] == :trackable_object
31
+ trackable_object_id = value[:reference_entity_id]
32
+ trackable_object_snapshot = get_trackable_object_snapshot(trackable_object_id)
33
+ property_ids = value[:selected_property_ids] & trackable_object_snapshot.property_ids
34
+ expand_trackable_object_properties(property_ids)
35
+ else
36
+ property_id = value[:reference_entity_id]
37
+ property_snapshot = get_property_snapshot(property_id)
38
+ expand_property(property_snapshot)
39
+ end
40
+ expanded_value = [expanqded_value] if value[:is_array]
41
+ [key, expanded_value]
42
+ end.to_h
43
+ {name: snapshot.name, description: snapshot.description, payload: expanded_payload}
44
+ end
45
+ end
46
+
47
+ def expand_trackable_object_properties(property_ids)
48
+ property_ids.map do |property_id|
49
+ property_snapshot = get_property_snapshot(property_id)
50
+ property_fields = expand_property(property_snapshot)
51
+
52
+ [property_snapshot.name, property_fields]
53
+ end.to_h
54
+
55
+ end
56
+
57
+ def expand_property(property_snapshot)
58
+ trackable_object_id = property_snapshot.trackable_object_id
59
+ if trackable_object_id
60
+ trackable_object_snapshot = get_trackable_object_snapshot(trackable_object_id)
61
+ property_ids = trackable_object_snapshot.property_ids
62
+ expanded_values = expand_trackable_object_properties(property_ids)
63
+ property_snapshot.is_array ? [expanded_values] : expanded_values
64
+ else
65
+ {
66
+ data_type: property_snapshot.data_type,
67
+ description: property_snapshot.description,
68
+ is_nullable: property_snapshot.is_nullable,
69
+ additional_instructions: property_snapshot.additional_instructions,
70
+ data_format_id: property_snapshot.data_format_id,
71
+ regex_validation: property_snapshot.regex_validation,
72
+ is_removed: property_snapshot.is_removed,
73
+ }
74
+ end
75
+ end
76
+
77
+ def get_trackable_object_snapshot(trackable_object_id)
78
+ Skee::App::TrackableObject::Service.get(
79
+ id: trackable_object_id,
80
+ change_request_id: @change_request_id
81
+ ).versioned_entity_snapshot
82
+ end
83
+
84
+ def get_property_snapshot(property_id)
85
+ Skee::App::Property::Service.get(
86
+ id: property_id,
87
+ change_request_id: @change_request_id
88
+ ).versioned_entity_snapshot
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,51 @@
1
+ require_relative '../../db/proto/tracking_spec'
2
+ module Skee
3
+ module App
4
+ module TrackingSpec
5
+ class Service
6
+ DB = Skee::DB::Proto
7
+
8
+ def self.list
9
+ DB::TrackingSpec.all
10
+ end
11
+
12
+ def self.get(params)
13
+ DB::TrackingSpec.find(params[:id])
14
+ end
15
+
16
+ def self.find_by(params)
17
+ DB::TrackingSpec.where(params)
18
+ end
19
+
20
+ def self.create(params)
21
+ # add any validation or filtering logic here to
22
+ # derive fields from params
23
+ fields = {
24
+ version_identifier: params[:version_identifier],
25
+ change_request_id: params[:change_request_id],
26
+ project_id: params[:project_id],
27
+ event_ids: params[:event_ids]
28
+ }
29
+ DB::TrackingSpec.create(fields)
30
+ end
31
+
32
+ def self.update(params)
33
+ # send valid fields excluding id
34
+ fields = {
35
+ version_identifier: params[:version_identifier],
36
+ change_request_id: params[:change_request_id],
37
+ project_id: params[:project_id],
38
+ event_ids: params[:event_ids]
39
+ }
40
+ tracking_spec = DB::TrackingSpec.find(params[:id])
41
+ tracking_spec.update(fields)
42
+ end
43
+
44
+ def self.delete(params)
45
+ tracking_spec = DB::TrackingSpec.find(params[:id])
46
+ tracking_spec.delete
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,61 @@
1
+ require_relative '../../app/change_request/service'
2
+ module Skee
3
+ module App
4
+ module TrackingSpec
5
+ class Validator
6
+ def initialize(params)
7
+ @params = params
8
+ end
9
+
10
+ ERRORS = Utils::Errors
11
+
12
+ def validate_create_params
13
+ validate_unique_version_identifier
14
+ validate_event_ids_exist
15
+ end
16
+
17
+ def validate_update_params
18
+ validate_unique_version_identifier
19
+ validate_tracking_spec_exists
20
+ validate_event_ids_exist
21
+ end
22
+
23
+ def validate_expand_params
24
+ validate_change_request
25
+ end
26
+
27
+ private
28
+
29
+ def validate_unique_version_identifier
30
+ return unless @params[:version_identifier]
31
+ tracking_spec = Skee::App::TrackingSpec::Service.find_by(
32
+ version_identifier: @params[:version_identifier]
33
+ )
34
+ return unless tracking_spec
35
+ raise ERRORS::NotAllowedToUpdate.new('Invalid parameter: Version Identifier should be unique.')
36
+ end
37
+
38
+ def validate_tracking_spec_exists
39
+ tracking_spec = Skee::App::TrackingSpec::Service.get(id: @params[:id])
40
+ return if tracking_spec
41
+ raise ERRORS::RecordNotFoundException.new('Invalid parameter: Tracking spec does not exist')
42
+ end
43
+
44
+ def validate_event_ids_exist
45
+ return if @params[:event_ids].empty?
46
+ events = Skee::App::Event::Service.list(ids: @params[:event_ids])
47
+ return if (@params[:event_ids] - events.map(&:id)).empty?
48
+ raise ERRORS::NotAllowedToUpdate.new('Invalid parameter: Event IDs do not exist')
49
+ end
50
+
51
+ def validate_change_request
52
+ raise ERRORS::RecordNotFoundException.new('Invalid change request') unless change_request
53
+ end
54
+
55
+ def change_request
56
+ @change_request ||= Skee::App::ChangeRequest::Service.get(id: @params[:change_request_id])
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,10 @@
1
+ module Skee
2
+ module App
3
+ module Utils
4
+ module Errors
5
+ class ValidationError < StandardError;
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ module Skee
2
+ module App
3
+ module Utils
4
+ module Errors
5
+ class UniquenessViolationException < StandardError; end
6
+ class RecordNotFoundException < StandardError; end
7
+ class NotAllowedToUpdate < StandardError; end
8
+ class NotAllowedToCancelChanges < StandardError; end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,110 @@
1
+ require_relative '../../app/change_request/service'
2
+ module Skee
3
+ module App
4
+ module VersionedEntity
5
+ class Entity
6
+ def initialize(entity)
7
+ @entity = entity
8
+ @db = Skee::App::DB_MAPPING_ENTITY[@entity]
9
+ end
10
+
11
+ attr_accessor :versioned_entity, :versioned_entity_snapshot
12
+
13
+ def list(ids:, change_request_id:)
14
+ ids = @db.all.map(&:id) if ids.empty?
15
+ return_entities = ids.map{ |id| get({
16
+ id: id,
17
+ change_request_id: change_request_id
18
+ })
19
+ }
20
+ end
21
+
22
+ def get(params)
23
+ versioned_entity_id = params[:id]
24
+ versioned_entity = @db.find(versioned_entity_id)
25
+ if change_request = Skee::App::ChangeRequest::Service.get(id: params[:change_request_id])
26
+ if change_request.change_set[@entity][versioned_entity_id]
27
+ entity_snapshot_id = change_request.change_set[@entity][versioned_entity_id].values.first
28
+ else
29
+ entity_snapshot_id = versioned_entity.latest_snapshot_id
30
+ end
31
+ else
32
+ entity_snapshot_id = versioned_entity.latest_snapshot_id
33
+ end
34
+ entity_snapshot = Skee::App::VersionedEntitySnapshot::Entity.new(@entity).get(id: entity_snapshot_id)
35
+ self.versioned_entity = versioned_entity
36
+ self.versioned_entity_snapshot = entity_snapshot
37
+ self
38
+ end
39
+
40
+ def create(params)
41
+ versioned_entity_params = {
42
+ # may need to add more fields
43
+ # snapshot_mapping: {params[:change_request_id] => entity_snapshot.id
44
+ }
45
+ versioned_entity = @db.create(versioned_entity_params)
46
+ entity_snapshot_params = params.merge(parent_entity_id: versioned_entity.id)
47
+ entity_snapshot = Skee::App::VersionedEntitySnapshot::Entity.new(@entity).create(entity_snapshot_params)
48
+ update_change_request(params[:change_request_id], versioned_entity.id, nil, entity_snapshot.id)
49
+ self.versioned_entity = versioned_entity
50
+ self.versioned_entity_snapshot = entity_snapshot
51
+ self
52
+ end
53
+
54
+ def update(update_params)
55
+ versioned_entity_id = update_params[:id]
56
+ change_request = Skee::App::ChangeRequest::Service.get(id: update_params[:change_request_id])
57
+ change_request.change_set[@entity] ||= {}
58
+ entity_snapshot = if change_request.change_set[@entity][versioned_entity_id]
59
+ update_existing_snapshot(change_request, update_params)
60
+ else
61
+ create_new_snapshot(update_params)
62
+ end
63
+ versioned_entity = @db.find(versioned_entity_id)
64
+ self.versioned_entity = versioned_entity
65
+ self.versioned_entity_snapshot = entity_snapshot
66
+ self
67
+ end
68
+
69
+ private
70
+
71
+ def update_existing_snapshot(change_request, update_params)
72
+ versioned_entity_id = update_params[:id]
73
+ entity_snapshot_id = change_request.change_set[@entity][versioned_entity_id].values.first
74
+ existing_entity_snapshot = Skee::App::VersionedEntitySnapshot::Entity.new(@entity).get(id: entity_snapshot_id)
75
+ update_params = update_params.select {|key, _| key != :id && key != "id"}
76
+ existing_entity_snapshot.update(update_params)
77
+ end
78
+
79
+ def create_new_snapshot(update_params)
80
+ versioned_entity_id = update_params[:id]
81
+ existing_entity = @db.find(versioned_entity_id)
82
+ entity_snapshot_id = existing_entity.latest_snapshot_id
83
+ current_entity_snapshot = Skee::App::VersionedEntitySnapshot::Entity.new(@entity).get(id: entity_snapshot_id)
84
+ current_entity_snapshot_params = current_entity_snapshot.to_h.select {|key, _| key != :id && key != "id"}
85
+ new_entity_snapshot_params = current_entity_snapshot_params.each do |key, _|
86
+ current_entity_snapshot_params[key] = update_params[key] if update_params.key?(key)
87
+ end
88
+ new_entity_snapshot_params[:previous_snapshot_id] = entity_snapshot_id
89
+ new_entity_snapshot_params[:is_removed] = true if update_params[:is_removed]
90
+ new_entity_snapshot = Skee::App::VersionedEntitySnapshot::Entity.new(@entity).create(new_entity_snapshot_params)
91
+ update_change_request(update_params[:change_request_id], versioned_entity_id, entity_snapshot_id, new_entity_snapshot.id)
92
+ new_entity_snapshot
93
+ end
94
+
95
+ def update_change_request(change_request_id, versioned_entity_id, current_entity_snapshot_id, new_entity_snapshot_id)
96
+ Skee::App::ChangeRequest::Service.update_change_set(
97
+ id: change_request_id,
98
+ changes: {
99
+ @entity => {
100
+ versioned_entity_id => {
101
+ current_entity_snapshot_id => new_entity_snapshot_id
102
+ }
103
+ }
104
+ }
105
+ )
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,47 @@
1
+ require_relative 'validator'
2
+ require_relative 'entity'
3
+ require_relative '../versioned_entity_snapshot/entity'
4
+ module Skee
5
+ module App
6
+ class VersionedEntityService
7
+ def self.list(ids: [], change_request_id: nil)
8
+ Skee::App::VersionedEntity::Entity.new(entity).list(ids: ids, change_request_id: change_request_id)
9
+ end
10
+
11
+ def self.get(params)
12
+ Skee::App::VersionedEntity::Entity.new(entity).get(params)
13
+ end
14
+
15
+ def self.create(params)
16
+ Skee::App::VersionedEntity::Validator.new(
17
+ params, entity
18
+ ).validate_create_params
19
+ create_fields = create_fields_keys.map do |key|
20
+ value = key == :prev_entity_id ? nil : params[key]
21
+ [key, value]
22
+ end.to_h
23
+ Skee::App::VersionedEntity::Entity.new(entity).create(create_fields)
24
+ end
25
+
26
+ def self.update(params)
27
+ Skee::App::VersionedEntity::Validator.new(
28
+ params, entity
29
+ ).validate_update_params
30
+ update_fields = params.slice(*update_fields_keys).compact
31
+ Skee::App::VersionedEntity::Entity.new(entity).update(update_fields)
32
+ end
33
+
34
+ def self.remove(params)
35
+ Skee::App::VersionedEntity::Validator.new(
36
+ params, entity
37
+ ).validate_remove_params
38
+ remove_fields = {
39
+ change_request_id: params[:change_request_id],
40
+ id: params[:id],
41
+ is_removed: true
42
+ }
43
+ Skee::App::VersionedEntity::Entity.new(entity).update(remove_fields)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,61 @@
1
+ require_relative '../../app/change_request/service'
2
+ module Skee
3
+ module App
4
+ module VersionedEntity
5
+ class Validator
6
+ def initialize(params, entity_type)
7
+ @params = params
8
+ @entity_type = entity_type
9
+ end
10
+
11
+ ERRORS = Utils::Errors
12
+
13
+ def validate_create_params
14
+ validate_change_request_status
15
+ validate_uniqueness_by_name
16
+ end
17
+
18
+ def validate_update_params
19
+ validate_versioned_entity_present
20
+ validate_change_request_status
21
+ validate_uniqueness_by_name
22
+ end
23
+
24
+ def validate_remove_params
25
+ validate_versioned_entity_present
26
+ validate_change_request_status
27
+ validate_uniqueness_by_name
28
+ end
29
+
30
+ private
31
+
32
+ def validate_versioned_entity_present
33
+ entity_instance = Skee::App::DB_MAPPING_ENTITY[@entity_type].find(@params[:id])
34
+ raise ERRORS::RecordNotFoundException.new('Resource not found') unless entity_instance
35
+ end
36
+
37
+ def validate_change_request_status
38
+ raise ERRORS::RecordNotFoundException.new('Invalid change request') unless change_request
39
+ raise ERRORS::NotAllowedToUpdate.new('Invalid change request') if change_request.status != 'open'
40
+ end
41
+
42
+ def validate_uniqueness_by_name
43
+ # todo: fix this when we know structure of tracking spec
44
+ # tracking_spec = Skee::App::TrackingSpec::Service.get(id: change_request.source_tracking_spec_id)
45
+ # existing_entity_ids = tracking_spec.entity_set[@entity_type]
46
+ # new_entity_change_set = change_request.change_set[@entity_type]
47
+ # return unless new_entity_change_set
48
+ # new_entity_ids = new_entity_change_set.values.flatten
49
+ # non_unique_name = Skee::App::DB_MAPPING_ENTITY[@entity_type].find_all(ids: (new_entity_ids + existing_entity_ids)).any? do |entity|
50
+ # entity.name == @params[:name]
51
+ # end
52
+ # raise ERRORS::UniquenessViolationException.new('Invalid name') if non_unique_name
53
+ end
54
+
55
+ def change_request
56
+ @change_request ||= Skee::App::ChangeRequest::Service.get(id: @params[:change_request_id])
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,32 @@
1
+ require_relative '../../app/change_request/service'
2
+ module Skee
3
+ module App
4
+ module VersionedEntitySnapshot
5
+ class Entity
6
+ def initialize(entity)
7
+ @entity = entity
8
+ @db = Skee::App::DB_MAPPING_ENTITY_SNAPSHOT[@entity]
9
+ end
10
+
11
+ def list(ids:)
12
+ return @db.all if ids.empty?
13
+ @db.find_all(ids: ids)
14
+ end
15
+
16
+ def get(params)
17
+ # add validator, to reject if nil, or does not exist.
18
+ @db.find(params[:id])
19
+ end
20
+
21
+ def create(params)
22
+ @db.create(params)
23
+ end
24
+
25
+ def update(update_params)
26
+ snapshot = @db.find(update_params[:id])
27
+ snapshot.update(update_params)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'grape'
3
+ require 'grape-entity'
4
+ require 'pry'
5
+ require 'dotenv'
6
+
7
+ require_relative '../app/app'
8
+ require_relative '../api/api'
9
+
@@ -0,0 +1,3 @@
1
+ require_relative './config/boot'
2
+
3
+ run Skee::API::API
@@ -0,0 +1,10 @@
1
+ require_relative './common/doc'
2
+ module Skee
3
+ module DB
4
+ module Proto
5
+ class ChangeRequest < Proto::Common::Doc
6
+ @all_docs = []
7
+ end
8
+ end
9
+ end
10
+ end